<html>
<head><meta charset="utf-8"><title>Alignment and raw pointer deref · t-lang · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/index.html">t-lang</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html">Alignment and raw pointer deref</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="232012526"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/232012526" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#232012526">(Mar 26 2021 at 18:33)</a>:</h4>
<p>Currently, the Reference states that the following is UB:</p>
<blockquote>
<p>Dereferencing (using the <code>*</code> operator on) a dangling or unaligned raw pointer.</p>
</blockquote>
<p>Now that one can create unaligned raw pointers via <code>addr_of!</code>, this is probably not what we want. It means that <code>addr_of!((*ptr).field)</code> is UB when <code>ptr</code> is unaligned, even if everything is dereferencable. This is despite the fact that <code>addr_of!</code> lets you create unaligned raw pointers! That seems counter-intuitive.</p>



<a name="232012585"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/232012585" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#232012585">(Mar 26 2021 at 18:33)</a>:</h4>
<p>The issue with clarifying this is that the following must be UB if <code>ptr</code> is unaligned:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="kd">let</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">*</span><span class="n">ptr</span><span class="p">;</span><span class="w"></span>
</code></pre></div>



<a name="232012805"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/232012805" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#232012805">(Mar 26 2021 at 18:35)</a>:</h4>
<p>The reason this makes a difference is that the latter code is really sugar for </p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="kd">let</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">place2value</span><span class="p">(</span><span class="o">*</span><span class="n">ptr</span><span class="p">);</span><span class="w"></span>
<span class="c1">// really, if ptr is a local variable, the full thing looks like</span>
<span class="kd">let</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">place2value</span><span class="p">(</span><span class="o">*</span><span class="n">place2value</span><span class="p">(</span><span class="n">ptr</span><span class="p">));</span><span class="w"></span>
<span class="c1">// but the access to the local variable does not matter here</span>
</code></pre></div>
<p>and it is the <code>place2value</code> coercion (also called "load"; corresponding to the <code>Copy</code>/<code>Move</code> MIR <code>Operand</code>s) that requires alignment. But AFAIK we currently don't have docs explaining how Rust with explicit place2value would look like, so I am not sure how to best document UB rules that crucially rely on this coercion...</p>



<a name="232015926"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/232015926" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> NeoRaider <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#232015926">(Mar 26 2021 at 19:00)</a>:</h4>
<p>Hmm, I'm unsure what I'd expect from the language as a learner.</p>
<p>As you wrote in <a href="https://github.com/rust-lang/rust/issues/73987">#73987</a>, dereferencing a dangling or misaligned raw pointer creates a place. In my intuition, a place is a more "direct" thing than a reference, so I'd argue that the validity rules for places should be at least as strict as the rules for references. But there is already at least one example in Rust where this doesn't hold: A path to a misaligned field of a packed struct yields a valid place, but no valid reference can be constructed from that place...</p>



<a name="232073453"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/232073453" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#232073453">(Mar 27 2021 at 08:03)</a>:</h4>
<p>The reference text says "dereferencing", so I think that constructing a place is not sufficient to count as UB by that description. It is only the parenthetical "(using the <code>*</code> operator on)" that is problematic</p>



<a name="232073557"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/232073557" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#232073557">(Mar 27 2021 at 08:05)</a>:</h4>
<p>How about a footnote on the parenthetical that mentions that in some contexts, like in <code>addr_of!</code> and <code>let _ = *ptr;</code>, there is no actual dereferencing happening and so UB does not occur. (For full details, see &lt;UCG discussion of places and values&gt;)</p>



<a name="232078797"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/232078797" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#232078797">(Mar 27 2021 at 09:52)</a>:</h4>
<p><span class="user-mention silent" data-user-id="271719">Mario Carneiro</span> <a href="#narrow/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref/near/232073453">said</a>:</p>
<blockquote>
<p>The reference text says "dereferencing", so I think that constructing a place is not sufficient to count as UB by that description. It is only the parenthetical "(using the <code>*</code> operator on)" that is problematic</p>
</blockquote>
<p>"dereferencing" is a very ambiguous term</p>



<a name="232078804"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/232078804" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#232078804">(Mar 27 2021 at 09:52)</a>:</h4>
<p>that's why I made it explicit that the <code>*</code> operator, i.e. place creation, counts as "dereferencing"</p>



<a name="232078823"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/232078823" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#232078823">(Mar 27 2021 at 09:53)</a>:</h4>
<p>that is, to my knowledge, consistent with C, where even creating a place from a NULL ptr us UB (leading to the famous elided NULL ptr check bug in the Linux kernel)</p>



<a name="232078876"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/232078876" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#232078876">(Mar 27 2021 at 09:54)</a>:</h4>
<p>To make things worse, <code>let _ = *ptr;</code> actually is <em>safe code</em> currently when <code>ptr</code> is raw. This is considered a bug, but it shows that the entire issue around when the UB arises is non-trivial.</p>



<a name="232078930"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/232078930" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#232078930">(Mar 27 2021 at 09:55)</a>:</h4>
<blockquote>
<p>But there is already at least one example in Rust where this doesn't hold: A path to a misaligned field of a packed struct yields a valid place, but no valid reference can be constructed from that place...</p>
</blockquote>
<p>That's a very good point -- unaligned places are already permitted in some situations, so maybe we should just entirely rid places of alignment assumptions and put them to the place-to-value coercion (and the place-to-ref operation <code>&amp;</code>, of course).<br>
But then it's still not easy to say this very explicitly -- basically we'd first need a chapter somewhere in the reference that discusses the place-to-value coercion explicitly (currently it only happens implicitly)</p>



<a name="232095912"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/232095912" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> lcnr <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#232095912">(Mar 27 2021 at 15:03)</a>:</h4>
<p>not really relevant to this discussion:</p>
<blockquote>
<p>we currently don't have docs explaining how Rust with explicit <code>place2value</code> would look like</p>
</blockquote>
<p>i think <code>place2value</code> is also implicit in C <span aria-label="thinking" class="emoji emoji-1f914" role="img" title="thinking">:thinking:</span>  are there languages where you can't just coerce places into values?</p>



<a name="232100844"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/232100844" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> NeoRaider <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#232100844">(Mar 27 2021 at 16:22)</a>:</h4>
<p><span class="user-mention silent" data-user-id="120791">RalfJ</span> <a href="#narrow/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref/near/232078930">said</a>:</p>
<blockquote>
<blockquote>
<p>But there is already at least one example in Rust where this doesn't hold: A path to a misaligned field of a packed struct yields a valid place, but no valid reference can be constructed from that place...</p>
</blockquote>
<p>That's a very good point -- unaligned places are already permitted in some situations, so maybe we should just entirely rid places of alignment assumptions and put them to the place-to-value coercion (and the place-to-ref operation <code>&amp;</code>, of course).<br>
But then it's still not easy to say this very explicitly -- basically we'd first need a chapter somewhere in the reference that discusses the place-to-value coercion explicitly (currently it only happens implicitly)</p>
</blockquote>
<p>An alternative would be to define a "packed place", which has different constraints than a regular place. A packed place wouldn't need to be aligned, but no references can be taken from it (which is what <span class="user-mention" data-user-id="120791">@RalfJ</span> is working towards anyways).</p>
<p>This would allow us to consider a "regular" place something that must be aligned and not dangle, so taking a reference would always be valid as long as the borrow checker allows it.</p>
<p>I would prefer this solution, as it seems more consistent to me.</p>



<a name="232100995"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/232100995" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> NeoRaider <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#232100995">(Mar 27 2021 at 16:25)</a>:</h4>
<p><span class="user-mention silent" data-user-id="120791">RalfJ</span> <a href="#narrow/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref/near/232078876">said</a>:</p>
<blockquote>
<p>To make things worse, <code>let _ = *ptr;</code> actually is <em>safe code</em> currently when <code>ptr</code> is raw. This is considered a bug, but it shows that the entire issue around when the UB arises is non-trivial.</p>
</blockquote>
<p>What is the desired behavior here? When the unsafe checker is fixed not to allow this, should it become UB for unaligned/danling <code>ptr</code>? In my opinion, it should be UB (again, arguing for consistency - are there similar constructs that this behavior would be (in)consistent with?)</p>



<a name="232101664"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/232101664" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#232101664">(Mar 27 2021 at 16:35)</a>:</h4>
<p>re "packed place", yeah I suppose that would also be an option</p>



<a name="232101720"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/232101720" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#232101720">(Mar 27 2021 at 16:36)</a>:</h4>
<p>but again, I feel rather strongly that <code>addr_of!((*ptr).field)</code> should be eventually allowed even when <code>ptr</code> is unaligned or dangles -- so all of what you propose is way too strict IMO. the only reason this is currently disallowed is that this is implemented via <code>getelementptr inbounds</code> in the LLVM backend, and the only reason we use <code>inbounds</code> is that there is no <code>getelementptr nooverflow</code>, and plain <code>getelementptr</code> pays quite a bit for having to support overflows (that's what I am told, anyway)</p>



<a name="232101748"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/232101748" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#232101748">(Mar 27 2021 at 16:37)</a>:</h4>
<p><span class="user-mention silent" data-user-id="294290">NeoRaider</span> <a href="#narrow/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref/near/232100995">said</a>:</p>
<blockquote>
<p><span class="user-mention silent" data-user-id="120791">RalfJ</span> <a href="#narrow/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref/near/232078876">said</a>:</p>
<blockquote>
<p>To make things worse, <code>let _ = *ptr;</code> actually is <em>safe code</em> currently when <code>ptr</code> is raw. This is considered a bug, but it shows that the entire issue around when the UB arises is non-trivial.</p>
</blockquote>
<p>What is the desired behavior here? When the unsafe checker is fixed not to allow this, should it become UB for unaligned/danling <code>ptr</code>? In my opinion, it should be UB (again, arguing for consistency - are there similar constructs that this behavior would be (in)consistent with?)</p>
</blockquote>
<p>I am not sure. If we want to make this UB we need to find a way to even represent this on the MIR level so Miri has a chance of flagging it.<br>
In my opinion, whether or not it is UB depends on whether or not we decide that a place-to-value coercion is happening here. If it is, then this is certainly UB -- this code would be equivalent to <code>let _val = *ptr</code> for an unused <code>_val</code>. If however we decide that <code>_</code> suppresses the place-to-value coercion, then I think this should not be UB.</p>



<a name="232101976"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/232101976" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#232101976">(Mar 27 2021 at 16:41)</a>:</h4>
<p>also see <a href="https://github.com/rust-lang/unsafe-code-guidelines/issues/261">https://github.com/rust-lang/unsafe-code-guidelines/issues/261</a></p>



<a name="232106961"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/232106961" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#232106961">(Mar 27 2021 at 18:00)</a>:</h4>
<p>What would it take to add a variant of gep for nooverflow to LLVM? Would that be the easiest solution to this problem?</p>



<a name="232107691"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/232107691" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#232107691">(Mar 27 2021 at 18:12)</a>:</h4>
<p><span class="user-mention silent" data-user-id="239881">Josh Triplett</span> <a href="#narrow/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref/near/232106961">said</a>:</p>
<blockquote>
<p>What would it take to add a variant of gep for nooverflow to LLVM? Would that be the easiest solution to this problem?</p>
</blockquote>
<p>I don't know, I am not an LLVM expert. What I said above is mostly repeating what I learnt from @rkruppe.</p>



<a name="232107716"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/232107716" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#232107716">(Mar 27 2021 at 18:14)</a>:</h4>
<p>it would be relatively easy to switch to <code>getelementptr</code> (codegen would have to distinguish raw place expressions from ref place expressions, but that should be feasible), but people knowing more about LLVM than I do said that'd be a bad idea in terms of lost optimization potential. I don't think this was actually measured though.</p>



<a name="232132121"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/232132121" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#232132121">(Mar 28 2021 at 01:34)</a>:</h4>
<p><span class="user-mention silent" data-user-id="120791">RalfJ</span> <a href="#narrow/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref/near/232078823">said</a>:</p>
<blockquote>
<p>that is, to my knowledge, consistent with C, where even creating a place from a NULL ptr us UB (leading to the famous elided NULL ptr check bug in the Linux kernel)</p>
</blockquote>
<p>Are you sure about this? I have read about the linux kernel bug before but IIRC it actually dereferenced the pointer (that is, it accessed memory at the location). Here's a snippet from <a href="https://lwn.net/Articles/342330/">LWN</a>:</p>
<div class="codehilite" data-code-language="C"><pre><span></span><code>    <span class="k">static</span> <span class="kt">unsigned</span> <span class="kt">int</span> <span class="n">tun_chr_poll</span><span class="p">(</span><span class="k">struct</span> <span class="nc">file</span> <span class="o">*</span><span class="n">file</span><span class="p">,</span> <span class="n">poll_table</span> <span class="o">*</span> <span class="n">wait</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="k">struct</span> <span class="nc">tun_file</span> <span class="o">*</span><span class="n">tfile</span> <span class="o">=</span> <span class="n">file</span><span class="o">-&gt;</span><span class="n">private_data</span><span class="p">;</span>
        <span class="k">struct</span> <span class="nc">tun_struct</span> <span class="o">*</span><span class="n">tun</span> <span class="o">=</span> <span class="n">__tun_get</span><span class="p">(</span><span class="n">tfile</span><span class="p">);</span>
        <span class="k">struct</span> <span class="nc">sock</span> <span class="o">*</span><span class="n">sk</span> <span class="o">=</span> <span class="n">tun</span><span class="o">-&gt;</span><span class="n">sk</span><span class="p">;</span>
        <span class="kt">unsigned</span> <span class="kt">int</span> <span class="n">mask</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>

        <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">tun</span><span class="p">)</span>
            <span class="k">return</span> <span class="n">POLLERR</span><span class="p">;</span>
</code></pre></div>
<p>The access in question is <code>tun-&gt;sk</code>, or <code>place2value((*tun).sk)</code>, which is definitely UB if <code>tun</code> is null.</p>



<a name="232132337"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/232132337" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#232132337">(Mar 28 2021 at 01:38)</a>:</h4>
<p>If you wanted to avoid the <code>place2value</code> here, you could write <code>&amp;tun-&gt;sk</code>, which would be equivalent to <code>addr_of!((*tun).sk)</code> in rust, and I think this should not be UB even if <code>tun</code> is null (although I'm guessing this is still UB in C, if the semantics of GEPi are anything to go by)</p>



<a name="232132452"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/232132452" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#232132452">(Mar 28 2021 at 01:40)</a>:</h4>
<p>In C++ you also have the option of <code>auto&amp; sk = tun-&gt;sk;</code> to suppress the <code>place2value</code></p>



<a name="232154476"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/232154476" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#232154476">(Mar 28 2021 at 09:19)</a>:</h4>
<blockquote>
<p>Are you sure about this? I have read about the linux kernel bug before but IIRC it actually dereferenced the pointer (that is, it accessed memory at the location).</p>
</blockquote>
<p>Hm, fair. But I am sure that clang translates field offset computations to <code>getelementptr inbounds</code>. ergo, <code>&amp;(ptr-&gt;field)</code> is UB in clang when <code>ptr</code> is NULL. I asume this is consistent with the C standard. (As you said.)</p>



<a name="232154596"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/232154596" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#232154596">(Mar 28 2021 at 09:21)</a>:</h4>
<blockquote>
<p>If you wanted to avoid the place2value here, you could write &amp;tun-&gt;sk, which would be equivalent to addr_of!((*tun).sk) in rust, and I think this should not be UB even if tun is null</p>
</blockquote>
<p>Yes, we agree on that. Some people think it should still be UB in case the address arithmetic overflows a <code>usize</code>; that's a shame because it means this cannot be made a safe operation but maybe that's an okay trade-off.</p>



<a name="232155756"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/232155756" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#232155756">(Mar 28 2021 at 09:46)</a>:</h4>
<p>Just to give a concrete example for why I think <code>addr_of!((*ptr).field)</code> should be allowed even when <code>ptr</code> dangles -- that is the only way I see to fix <a href="https://github.com/Gilnaa/memoffset/issues/49">https://github.com/Gilnaa/memoffset/issues/49</a>.</p>



<a name="232165208"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/232165208" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> NeoRaider <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#232165208">(Mar 28 2021 at 12:54)</a>:</h4>
<p><span class="user-mention silent" data-user-id="120791">RalfJ</span> <a href="#narrow/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref/near/232155756">said</a>:</p>
<blockquote>
<p>Just to give a concrete example for why I think <code>addr_of!((*ptr).field)</code> should be allowed even when <code>ptr</code> dangles -- that is the only way I see to fix <a href="https://github.com/Gilnaa/memoffset/issues/49">https://github.com/Gilnaa/memoffset/issues/49</a>.</p>
</blockquote>
<p>IMO, <code>offset_of!()</code> is special (and useful) enough that it could be implemented as a compiler intrinsic (not sure if that's the right term if it's a macro?)</p>



<a name="232166479"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/232166479" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#232166479">(Mar 28 2021 at 13:16)</a>:</h4>
<p>That would be another way to avoid the stack allocation, yeah, but it seems rather heavy-handed -- and it's just one example. In general I think we should have as little UB as we can, and motivate UB by optimizations. The entire point of raw pointers is to write low-level tricky code with as much programmer control as possible, so every bit of UB we can remove here is a win, IMO. That's the entire reason why we have references and raw pointers: to have good optimizations on references, and to let programmers "do their thing" with as little compiler interference as possible for raw pointers.</p>



<a name="232166603"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/232166603" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#232166603">(Mar 28 2021 at 13:18)</a>:</h4>
<p><span class="user-mention" data-user-id="294290">@NeoRaider</span> I forgot, what is your opinion on <code>addr_of!((*ptr).field)</code> where <code>ptr</code> is dereferencable but misaligned?</p>



<a name="232167031"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/232167031" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> NeoRaider <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#232167031">(Mar 28 2021 at 13:26)</a>:</h4>
<p><span class="user-mention silent" data-user-id="120791">RalfJ</span> <a href="#narrow/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref/near/232166479">said</a>:</p>
<blockquote>
<p>In general I think we should have as little UB as we can, and motivate UB by optimizations.</p>
</blockquote>
<p>I see, this is where our priorities differ. I'd like the rules for what is UB to be as simple and consistent as possible, to make them understandable for humans. The UB happening at some implicit place-to-value conversion is way too subtle IMO.</p>



<a name="232167498"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/232167498" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> NeoRaider <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#232167498">(Mar 28 2021 at 13:34)</a>:</h4>
<p><span class="user-mention silent" data-user-id="120791">RalfJ</span> <a href="#narrow/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref/near/232166603">said</a>:</p>
<blockquote>
<p><span class="user-mention silent" data-user-id="294290">NeoRaider</span> I forgot, what is your opinion on <code>addr_of!((*ptr).field)</code> where <code>ptr</code> is dereferencable but misaligned?</p>
</blockquote>
<p>I think that <code>*ptr</code> by itself should already be UB for misaligned <code>ptr</code>, and I don't think it would be a good idea to make <code>addr_of!()</code> magic to avoid UB, so that whole expression would also be UB.</p>



<a name="232167507"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/232167507" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> NeoRaider <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#232167507">(Mar 28 2021 at 13:34)</a>:</h4>
<p>Going with the idea of packed places, <code>addr_of!()</code> would still be useful for that. But <code>*ptr</code> can't result in a packed place, or <code>&amp;*ptr</code> would become invalid.</p>



<a name="232167628"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/232167628" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> NeoRaider <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#232167628">(Mar 28 2021 at 13:37)</a>:</h4>
<p><span class="user-mention silent" data-user-id="120791">RalfJ</span> <a href="#narrow/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref/near/232166479">said</a>:</p>
<blockquote>
<p>That would be another way to avoid the stack allocation, yeah, but it seems rather heavy-handed -- and it's just one example.</p>
</blockquote>
<p>Could you show me a few other examples?</p>



<a name="232170965"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/232170965" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#232170965">(Mar 28 2021 at 14:40)</a>:</h4>
<p><span class="user-mention silent" data-user-id="294290">NeoRaider</span> <a href="#narrow/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref/near/232167031">said</a>:</p>
<blockquote>
<p><span class="user-mention silent" data-user-id="120791">RalfJ</span> <a href="#narrow/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref/near/232166479">said</a>:</p>
<blockquote>
<p>In general I think we should have as little UB as we can, and motivate UB by optimizations.</p>
</blockquote>
<p>I see, this is where our priorities differ. I'd like the rules for what is UB to be as simple and consistent as possible, to make them understandable for humans. The UB happening at some implicit place-to-value conversion is way too subtle IMO.</p>
</blockquote>
<p>I agree simplicity and consistency is important. I don't think there is a conflict here, i.e., I don't think my proposal unduly hurts simplicity or consistency.<br>
Notice that for references, <em>we don't need</em> to have a rule saying that <code>*x</code> is UB if <code>x</code> is unaligned or dangles -- it is impossible to even create an unaligned/dangling reference without causing UB! So <a href="https://doc.rust-lang.org/reference/behavior-considered-undefined.html">in our UB definition</a>, the UB on <code>*ptr</code> is already a special case:</p>
<blockquote>
<p>Dereferencing (using the * operator on) a dangling or unaligned raw pointer.</p>
</blockquote>
<p>There is no such clause for references. So there is no question whether raw pointers have a special case in the UB rules, there just is a question of what that special case looks like. Thus I don't think my proposal increases complexity sufficiently to cause concern on that front.</p>



<a name="232171148"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/232171148" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#232171148">(Mar 28 2021 at 14:44)</a>:</h4>
<p><span class="user-mention silent" data-user-id="294290">NeoRaider</span> <a href="#narrow/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref/near/232167628">said</a>:</p>
<blockquote>
<p><span class="user-mention silent" data-user-id="120791">RalfJ</span> <a href="#narrow/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref/near/232166479">said</a>:</p>
<blockquote>
<p>That would be another way to avoid the stack allocation, yeah, but it seems rather heavy-handed -- and it's just one example.</p>
</blockquote>
<p>Could you show me a few other examples?</p>
</blockquote>
<p>I don't have other concrete examples, but I think <code>addr_of!((*ptr).field)</code> is the obvious way to get the field of an unaligned ptr, and hence needs to be allowed <em>at least</em> in case <code>ptr</code> is dereferencable but misaligned. It's hard to do this computation in another way. Not only that, this code is actually fine (UB-free) under our current lowering to LLVM, so allowing it will not invalidate any optimizations that we currently perform.</p>



<a name="232171169"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/232171169" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#232171169">(Mar 28 2021 at 14:45)</a>:</h4>
<p><span class="user-mention silent" data-user-id="294290">NeoRaider</span> <a href="#narrow/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref/near/232167498">said</a>:</p>
<blockquote>
<p>I think that <code>*ptr</code> by itself should already be UB for misaligned <code>ptr</code>, and I don't think it would be a good idea to make <code>addr_of!()</code> magic to avoid UB, so that whole expression would also be UB.</p>
</blockquote>
<p>so what do you propose people do when they have a possibly-misaligned <code>ptr</code> and need to get the address of a field?</p>



<a name="232171306"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/232171306" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#232171306">(Mar 28 2021 at 14:47)</a>:</h4>
<p>I feel like I'm in a weird mirror universe, because usually I'm the one arguing for UB. ;) And indeed I think the burden of proof for UB should be on the people that want more UB, to show that the high price the language pays for this (entirely ruling out certain programming patterns in ways that are very hard to detect in a large program) is worth it. That's why Stacked Borrows is always motivated with optimizations.<br>
So, in that spirit -- what important optimizations do you think are enabled by making this UB?</p>



<a name="232173864"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/232173864" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#232173864">(Mar 28 2021 at 15:33)</a>:</h4>
<blockquote>
<p>I think the burden of proof for UB should be on the people that want more UB, to show that the high price the language pays for this (entirely ruling out certain programming patterns in ways that are very hard to detect in a large program) is worth it.</p>
</blockquote>
<p><span aria-label="tada" class="emoji emoji-1f389" role="img" title="tada">:tada:</span></p>



<a name="232174068"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/232174068" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#232174068">(Mar 28 2021 at 15:36)</a>:</h4>
<p><span class="user-mention silent" data-user-id="120791">RalfJ</span> <a href="#narrow/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref/near/232171169">said</a>:</p>
<blockquote>
<p>so what do you propose people do when they have a possibly-misaligned <code>ptr</code> and need to get the address of a field?</p>
</blockquote>
<p>FWIW, here's the best I know to do:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="p">(</span><span class="n">ptr</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="o">*</span><span class="k">const</span><span class="w"> </span><span class="kt">u8</span><span class="p">).</span><span class="n">wrapping_offset</span><span class="p">(</span><span class="n">offset_of</span><span class="o">!</span><span class="p">(</span><span class="n">StructType</span><span class="p">,</span><span class="w"> </span><span class="n">field</span><span class="p">))</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="o">*</span><span class="k">const</span><span class="w"> </span><span class="n">FieldType</span><span class="w"></span>
</code></pre></div>



<a name="232179702"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/232179702" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thom Chiovoloni <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#232179702">(Mar 28 2021 at 17:12)</a>:</h4>
<p>is there a reason that's wrapping_offset? i was under the understanding that that couldn't wrap</p>



<a name="232180374"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/232180374" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#232180374">(Mar 28 2021 at 17:24)</a>:</h4>
<p>well I guess <code>offset</code> would also work here since we assume the pointer is dereferencable</p>



<a name="232181276"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/232181276" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#232181276">(Mar 28 2021 at 17:41)</a>:</h4>
<p>Note that:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="kd">let</span><span class="w"> </span><span class="n">uninit</span>: <span class="o">*</span><span class="k">const</span><span class="w"> </span><span class="n">SomeType</span><span class="p">;</span><span class="w"> </span><span class="c1">// No initializer!</span>
<span class="kd">let</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">*</span><span class="n">uninit</span><span class="p">;</span><span class="w"></span>
</code></pre></div>
<p>currently compiles fine (even with an empty type); which seems related to that "dereference without using <code>unsafe</code>" issue, but to me is a bit different: the fact that a knowingly uninit local is having the <code>*</code> operator applied to it without any issues whatsoever showcases that the language did not intend for "dereference-to-a-place" to require an actual dereference or even just reading the pointer value.</p>
<p>Maybe it's also my C mind that is so used to the <code>thing_t * ptr; ptr = malloc(sizeof(*ptr));</code> pattern, but the fact that dereference-to-place is not a real dereference, just a syntactic way to express a place to the compiler seems very hard-wired into my brain (and I can thus assume that it will also be the case of other programmers), which is especially important when dealing with <code>addr_of!</code> and field-offset shenanigans.</p>
<p>All that to say: I do see reasons to keep the "deref-to-a-place" be a no-op (and thus not UB) until such a place is actually "used" (<em>e.g.</em>, coerced to a value), and as you mentioned, we have yet to see instances where that being UB since the beginning would enable more powerful optimizations. The only argument in that direction would be to try and feature simpler UB rules, but doing that just to <em>add</em> more instances of UB seems counterproductive <span aria-label="big smile" class="emoji emoji-1f604" role="img" title="big smile">:big_smile:</span></p>



<a name="232196608"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/232196608" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> NeoRaider <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#232196608">(Mar 28 2021 at 22:05)</a>:</h4>
<p><span class="user-mention silent" data-user-id="232018">Daniel Henry-Mantilla</span> <a href="#narrow/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref/near/232181276">said</a>:</p>
<blockquote>
<p>Maybe it's also my C mind that is so used to the <code>thing_t * ptr; ptr = malloc(sizeof(*ptr));</code> pattern, but the fact that dereference-to-place is not a real dereference, just a syntactic way to express a place to the compiler seems very hard-wired into my brain (and I can thus assume that it will also be the case of other programmers), which is especially important when dealing with <code>addr_of!</code> and field-offset shenanigans.</p>
</blockquote>
<p>Well, that's more the magic of the C sizeof operator, which doesn't actually run any of the code it's applied to. <code>printf("%d\n", sizeof(printf("Foo")));</code> will just print the size of an int and not "Foo". Code that is not run can not have UB.</p>
<p>This only works because sizeof only cares about the type of the expression it is applied to, to this is not applicable to <code>addr_of!()</code>.</p>



<a name="232197135"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/232197135" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> NeoRaider <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#232197135">(Mar 28 2021 at 22:15)</a>:</h4>
<p><span class="user-mention silent" data-user-id="120791">RalfJ</span> <a href="#narrow/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref/near/232171306">said</a>:</p>
<blockquote>
<p>I feel like I'm in a weird mirror universe, because usually I'm the one arguing for UB. ;) And indeed I think the burden of proof for UB should be on the people that want more UB, to show that the high price the language pays for this (entirely ruling out certain programming patterns in ways that are very hard to detect in a large program) is worth it. That's why Stacked Borrows is always motivated with optimizations.<br>
So, in that spirit -- what important optimizations do you think are enabled by making this UB?</p>
</blockquote>
<p>I wasn't thinking about optimizations, just about keeping the language simple to learn/teach by avoiding a rule that feels unnecessarily complex to me.</p>



<a name="232198303"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/232198303" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> NeoRaider <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#232198303">(Mar 28 2021 at 22:39)</a>:</h4>
<p>Not sure if the following snippet if of any relevance for the question, but if <code>*ptr</code> is not UB by itself for unaligned/dangling <code>ptr</code>, where exactly would the UB happen here? At the point where the place of <code>*ptr</code> is passed to the outside of the unsafe block?</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">fn</span> <span class="nf">foo</span><span class="p">(</span><span class="n">ptr</span>: <span class="o">*</span><span class="k">const</span><span class="w"> </span><span class="kt">i32</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">_x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">&amp;</span><span class="k">unsafe</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="o">*</span><span class="n">ptr</span><span class="w"> </span><span class="p">};</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>



<a name="232198474"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/232198474" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> NeoRaider <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#232198474">(Mar 28 2021 at 22:43)</a>:</h4>
<p>Hmm, maybe my question doesn't make sense, and the unsafe block doesn't contain the UB itself, but it allows the "unsafety" to escape the block, so the UB actually happens when the reference is taken.</p>



<a name="232200095"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/232200095" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#232200095">(Mar 28 2021 at 23:13)</a>:</h4>
<p>Note that an unsafe block acts like a block, meaning that it moves the contents of the dereference. Note the error:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">fn</span> <span class="nf">foo</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">(</span><span class="n">ptr</span>: <span class="o">*</span><span class="k">const</span><span class="w"> </span><span class="n">T</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="o">&amp;</span><span class="k">unsafe</span><span class="w"> </span><span class="p">{</span><span class="o">*</span><span class="n">ptr</span><span class="p">};</span><span class="w"> </span><span class="c1">// cannot move out of `*ptr` which is behind a raw pointer</span>
<span class="p">}</span><span class="w"></span>
<span class="k">unsafe</span><span class="w"> </span><span class="k">fn</span> <span class="nf">bar</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">(</span><span class="n">ptr</span>: <span class="o">*</span><span class="k">const</span><span class="w"> </span><span class="n">T</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="o">&amp;</span><span class="p">{</span><span class="o">*</span><span class="n">ptr</span><span class="p">};</span><span class="w"> </span><span class="c1">// cannot move out of `*ptr` which is behind a raw pointer</span>
<span class="p">}</span><span class="w"></span>
<span class="k">unsafe</span><span class="w"> </span><span class="k">fn</span> <span class="nf">baz</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">(</span><span class="n">ptr</span>: <span class="o">*</span><span class="k">const</span><span class="w"> </span><span class="n">T</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="o">&amp;</span><span class="p">(</span><span class="o">*</span><span class="n">ptr</span><span class="p">);</span><span class="w"> </span><span class="c1">// ok</span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>That means that you generally can't play with places across an unsafe block, because the block itself inserts a <code>place2value</code> in the middle (and the <code>&amp;</code> is just borrowing the newly created temporary)</p>



<a name="232254012"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/232254012" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#232254012">(Mar 29 2021 at 11:41)</a>:</h4>
<p><span class="user-mention silent" data-user-id="294290">NeoRaider</span> <a href="#narrow/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref/near/232196608">said</a>:</p>
<blockquote>
<p>This only works because sizeof only cares about the type of the expression it is applied to, to this is not applicable to <code>addr_of!()</code>.</p>
</blockquote>
<p>Well <code>sizeof</code> was just an example. For a more relevant one, there is the pervasive <code>offsetof</code> macro in C:</p>
<ul>
<li><a href="https://stackoverflow.com/a/24917265">bunch of different macro implementations</a>, all dereferencing <code>NULL</code> / <code>0</code>;</li>
<li><a href="https://stackoverflow.com/a/61922720">quotes from the C standard</a></li>
</ul>
<p>All in all, the idea is that the operation <code>|p| addr_of!( (*p).field )</code> is the closest way to express in Rust what these C macros are based on: pointer offsetting / an addition with a constant offset; <strong>whether <code>p</code> is an actually dereferenceable pointer is unnecessary</strong>. Some extra requirements might be <em>desirable</em>, though, provided one can reap enough optimizations off it to be worth the extra cases of UB.</p>
<ul>
<li>The most basic such example is that of marking the addition as a non-overflowing one, which rules out maximal addresses.</li>
<li>Given the LLVM backend, the only way to currently express this operation in an optimized way seems to be with the <code>inbounds</code> annotation on <code>getelementptr</code>, which seems to require that the pointer point to an actual allocation. So right now this seems to be a safety requirement of <code>addr_of!</code> / to-place-dereference: some UB has been (conservatively) introduced, but with an optimization to justify it.</li>
<li>Regarding alignment, I could envision one optimization, but it looks a bit niche: if the pointer is well aligned, and the offset small enough (smaller than this very alignment), then the offset may be performed with a bitwise <code>|</code> operation rather than an actual addition. I don't know CPUs well enough to know if that can make a difference, and if the compiler backend(s) (llvm) are able to express this optimization yet. But assuming they would eventually be so, and assuming <code>|</code> can operate faster than <code>+</code>, then that <em>could</em> justify introducing this extra case of UB.</li>
</ul>
<p>To be conservative, if we consider this third case to be an option we could want to take, then we should definitely start by conservatively declaring unaligned to-place-dereference to be UB as well. Otherwise, by lack of any optimizations that would be lost if unaligned to-place-dereferences were supported, there does not seem to be a compelling reason to rule it out: "simplicity of UB rules", in this instance, does not seem to make much sense.</p>
<p>Indeed, we can define those rules as a whitelist ("to-place-dereference of a raw pointer is UB unless …"); that is, clearly spell out the white-listed cases. If anybody gets confused, they are free to avoid all the whitelisted cases entirely: <em>a use case not being UB does not mandate it be used</em>: we, as programmers, are free to treat it as "dangerously close to UB and avoid it".</p>
<p>I just find it unrealistic <em>w.r.t.</em> the current code out there which <a href="https://grep.app/search?q=%21%20offset_%3Fof&amp;regexp=true&amp;filter[lang][0]=Rust">often ends up ruling out their own <code>offsetof!</code>-like macros</a> to go and add yet another footgun there, just for the sake of "being pedantic" (≠ for the sake of enabling compiler optimizations).</p>



<a name="232558214"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/232558214" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#232558214">(Mar 31 2021 at 09:08)</a>:</h4>
<blockquote>
<p>currently compiles fine (even with an empty type); which seems related to that "dereference without using unsafe" issue, but to me is a bit different: the fact that a knowingly uninit local is having the * operator applied to it without any issues whatsoever showcases that the language did not intend for "dereference-to-a-place" to require an actual dereference or even just reading the pointer value.</p>
</blockquote>
<p>I think this is just an oversight of doing init checking on the MIR.</p>



<a name="232558645"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/232558645" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#232558645">(Mar 31 2021 at 09:11)</a>:</h4>
<blockquote>
<p>I just find it unrealistic w.r.t. the current code out there which often ends up ruling out their own offsetof!-like macros to go and add yet another footgun there, just for the sake of "being pedantic" (≠ for the sake of enabling compiler optimizations).</p>
</blockquote>
<p>Yeah, many of those are UB... that's why the offset_of crate exists, but it seems that is not known widely enough :/</p>



<a name="232558844"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/232558844" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#232558844">(Mar 31 2021 at 09:13)</a>:</h4>
<blockquote>
<p>Given the LLVM backend, the only way to currently express this operation in an optimized way seems to be with the inbounds annotation on getelementptr, which seems to require that the pointer point to an actual allocation. So right now this seems to be a safety requirement of addr_of! / to-place-dereference: some UB has been (conservatively) introduced, but with an optimization to justify it.</p>
</blockquote>
<p>well, that UB could still be delayed -- really it's the operation of computing the field place from the struct place that needs to make the inbounds (or nooverflow) requirement. just <em>creating</em> the struct place could be fine even when it dangles / is misaligned.</p>



<a name="232610937"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/232610937" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> NeoRaider <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#232610937">(Mar 31 2021 at 15:25)</a>:</h4>
<p>If we allow this, are there any useful and valid operations except for <code>addr_of!</code> (and constructions based on <code>addr_of!</code>) that can be performed on an unaligned or dangling place?</p>



<a name="232627831"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/232627831" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#232627831">(Mar 31 2021 at 17:03)</a>:</h4>
<p><span class="user-mention silent" data-user-id="294290">NeoRaider</span> <a href="#narrow/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref/near/232610937">said</a>:</p>
<blockquote>
<p>If we allow this, are there any useful and valid operations except for <code>addr_of!</code> (and constructions based on <code>addr_of!</code>) that can be performed on an unaligned or dangling place?</p>
</blockquote>
<p>currently, no. but it could be an avenue towards relaxing the rules for field offsets towards "must not overflow". and then there'd be useful and valid operations on such places.</p>



<a name="232723372"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/232723372" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> NeoRaider <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#232723372">(Apr 01 2021 at 08:49)</a>:</h4>
<p><span class="user-mention" data-user-id="120791">@RalfJ</span>  I'm missing context again, can you give an example for such an operation?</p>



<a name="232920587"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/232920587" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#232920587">(Apr 02 2021 at 16:37)</a>:</h4>
<p>you can go to a field place</p>



<a name="232920612"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/232920612" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#232920612">(Apr 02 2021 at 16:37)</a>:</h4>
<p>like, <code>addr_of!(dangling_place.field)</code> could be okay</p>



<a name="232920735"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/232920735" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#232920735">(Apr 02 2021 at 16:38)</a>:</h4>
<p><span class="user-mention" data-user-id="294290">@NeoRaider</span>  or is that what you mean by "constructions based on <code>addr_of!</code>?</p>



<a name="232940806"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/232940806" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> NeoRaider <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#232940806">(Apr 02 2021 at 19:23)</a>:</h4>
<p><span class="user-mention silent" data-user-id="120791">RalfJ</span> <a href="#narrow/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref/near/232920735">said</a>:</p>
<blockquote>
<p><span class="user-mention silent" data-user-id="294290">NeoRaider</span>  or is that what you mean by "constructions based on <code>addr_of!</code>?</p>
</blockquote>
<p>Yes, that's one of the uses I was thinking of.</p>



<a name="232941559"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/232941559" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#232941559">(Apr 02 2021 at 19:30)</a>:</h4>
<p><span class="user-mention" data-user-id="294290">@NeoRaider</span> To probe your intuition re: your <a href="#narrow/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref/near/232100844">earlier comment</a>: If <code>ptr: *const T</code>, does constructing the place <code>*ptr</code> require the memory to be a valid <code>T</code>? You said "taking a reference would always be valid as long as the borrow checker allows it" which would seem to suggest yes. But then if <code>ptr: *const (bool, u8)</code> is it valid to do <code>let x = (*ptr).1;</code> if the first byte is not a bool?</p>



<a name="232959168"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/232959168" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> NeoRaider <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#232959168">(Apr 02 2021 at 22:27)</a>:</h4>
<p><span class="user-mention silent" data-user-id="271719">Mario Carneiro</span> <a href="#narrow/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref/near/232941559">said</a>:</p>
<blockquote>
<p><span class="user-mention silent" data-user-id="294290">NeoRaider</span> To probe your intuition re: your <a href="#narrow/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref/near/232100844">earlier comment</a>: If <code>ptr: *const T</code>, does constructing the place <code>*ptr</code> require the memory to be a valid <code>T</code>? You said "taking a reference would always be valid as long as the borrow checker allows it" which would seem to suggest yes. But then if <code>ptr: *const (bool, u8)</code> is it valid to do <code>let x = (*ptr).1;</code> if the first byte is not a bool?</p>
</blockquote>
<p>That's an interesting question, I'm not sure yet.  I assume this is valid in current Rust?</p>
<p>I hadn't thought about validity of values when I wrote that comment, that's a good point I need to look into.</p>



<a name="232961322"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/232961322" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#232961322">(Apr 02 2021 at 22:56)</a>:</h4>
<p>Yes, this is valid in current rust, or at least under stacked borrows / miri. The act of reading <code>let x: u8 = (*ptr).1;</code> only asserts the validity of the second part of the tuple in memory at the type <code>u8</code>, meaning that the <code>u8</code> has to be initialized, but otherwise no constraints are applied to the type, and the <code>bool</code> part can be whatever it wants to be. What's more, you can even do the equivalent of this in <em>safe</em> code, with partially moved memory:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">pub</span><span class="w"> </span><span class="k">fn</span> <span class="nf">foo</span><span class="p">(</span><span class="k">mut</span><span class="w"> </span><span class="n">ptr</span>: <span class="nb">Box</span><span class="o">&lt;</span><span class="p">(</span><span class="nb">String</span><span class="p">,</span><span class="w"> </span><span class="kt">u8</span><span class="p">)</span><span class="o">&gt;</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="nb">drop</span><span class="p">((</span><span class="o">*</span><span class="n">ptr</span><span class="p">).</span><span class="mi">0</span><span class="p">);</span><span class="w"></span>
<span class="w">    </span><span class="p">(</span><span class="o">*</span><span class="n">ptr</span><span class="p">).</span><span class="mi">1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">25</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="fm">println!</span><span class="p">(</span><span class="s">"{}"</span><span class="p">,</span><span class="w"> </span><span class="p">(</span><span class="o">*</span><span class="n">ptr</span><span class="p">).</span><span class="mi">1</span><span class="p">);</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>



<a name="232991089"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/232991089" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#232991089">(Apr 03 2021 at 08:24)</a>:</h4>
<blockquote>
<p>What's more, you can even do the equivalent of this in safe code, with partially moved memory:</p>
</blockquote>
<p>That's not equivalent; the validity guarantee remains valid after dropping.</p>



<a name="233003780"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/233003780" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#233003780">(Apr 03 2021 at 12:38)</a>:</h4>
<p>So, this whole thread is talking about a concrete example / disparity which hasn't been explicitly spelled out yet. To make things clearer (at least to me), here I go:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="cp">#[repr(C, packed)]</span><span class="w"></span>
<span class="k">struct</span> <span class="nc">Outer</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">_pad</span>: <span class="kt">u8</span><span class="p">,</span><span class="w"> </span><span class="n">inner</span>: <span class="nc">Inner</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="c1">// inner is unaligned</span>
<span class="k">struct</span> <span class="nc">Inner</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">field</span>: <span class="nc">Field</span><span class="p">,</span><span class="w"> </span><span class="n">_align</span>: <span class="p">[</span><span class="kt">u16</span><span class="p">;</span><span class="w"> </span><span class="mi">0</span><span class="p">]</span><span class="w"> </span><span class="p">}</span><span class="w"></span>

<span class="kd">let</span><span class="w"> </span><span class="n">storage</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">MaybeUninit</span>::<span class="o">&lt;</span><span class="n">Outer</span><span class="o">&gt;</span>::<span class="n">uninit</span><span class="p">();</span><span class="w"></span>
<span class="kd">let</span><span class="w"> </span><span class="n">at_outer</span>: <span class="o">*</span><span class="k">const</span><span class="w"> </span><span class="n">Outer</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">storage</span><span class="p">.</span><span class="n">as_ptr</span><span class="p">();</span><span class="w"></span>

<span class="kd">let</span><span class="w"> </span><span class="n">at_field</span>: <span class="o">*</span><span class="k">const</span><span class="w"> </span><span class="n">Field</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">if</span><span class="w"> </span>::<span class="n">rand</span>::<span class="n">random</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">ptr</span>::<span class="n">addr_of</span><span class="o">!</span><span class="p">(</span><span class="w"> </span><span class="p">(</span><span class="o">*</span><span class="n">at_outer</span><span class="p">).</span><span class="n">inner</span><span class="p">.</span><span class="n">field</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="c1">// OK</span>
<span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">at_inner</span>: <span class="o">*</span><span class="k">const</span><span class="w"> </span><span class="n">Inner</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ptr</span>::<span class="n">addr_of</span><span class="o">!</span><span class="p">(</span><span class="w"> </span><span class="p">(</span><span class="o">*</span><span class="n">at_outer</span><span class="p">).</span><span class="n">inner</span><span class="w"> </span><span class="p">);</span><span class="w"></span>
<span class="w">    </span><span class="n">ptr</span>::<span class="n">addr_of</span><span class="o">!</span><span class="p">(</span><span class="w"> </span><span class="p">(</span><span class="o">*</span><span class="n">at_inner</span><span class="p">).</span><span class="n">field</span><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="c1">// UB!</span>
<span class="p">};</span><span class="w"></span>
</code></pre></div>



<a name="233003812"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/233003812" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#233003812">(Apr 03 2021 at 12:38)</a>:</h4>
<p><span class="user-mention" data-user-id="294290">@NeoRaider</span> would you say that the second branch being UB is <em>less</em> confusing than it not being UB?</p>



<a name="233003944"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/233003944" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#233003944">(Apr 03 2021 at 12:41)</a>:</h4>
<p>(FWIW, the first branch being OK is absolutely required -- this is <em>the</em> way to get a ptr to an uninit field so that you can initialize it; it is the only way not involving horrible <code>offset_of!</code> based address arithmetic)</p>



<a name="233004011"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/233004011" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#233004011">(Apr 03 2021 at 12:42)</a>:</h4>
<p><span class="user-mention" data-user-id="232018">@Daniel Henry-Mantilla</span> thanks for the example; I had something like this in my mind when I asked the question and started this thread, but didn't find a way to express it as clearly as that :)</p>



<a name="233005249"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/233005249" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> NeoRaider <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#233005249">(Apr 03 2021 at 13:07)</a>:</h4>
<p><span class="user-mention silent" data-user-id="232018">Daniel Henry-Mantilla</span> <a href="#narrow/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref/near/233003812">said</a>:</p>
<blockquote>
<p><span class="user-mention silent" data-user-id="294290">NeoRaider</span> would you say that the second branch being UB is <em>less</em> confusing than it not being UB?</p>
</blockquote>
<p>Thanks for the example. I think when looking at <code>addr_of!</code> in isolation, it would be less confusing when the second branch isn't UB.</p>
<p>But for initialized <code>(*at_outer).inner</code> and <code>Inner : Copy</code>, copying <code>field</code> would still be OK in the first branch and UB in the second:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="kd">let</span><span class="w"> </span><span class="n">field</span>: <span class="nc">Field</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">if</span><span class="w"> </span>::<span class="n">rand</span>::<span class="n">random</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">     </span><span class="p">(</span><span class="o">*</span><span class="n">at_outer</span><span class="p">).</span><span class="n">inner</span><span class="p">.</span><span class="n">field</span><span class="w">  </span><span class="c1">// OK</span>
<span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">at_inner</span>: <span class="o">*</span><span class="k">const</span><span class="w"> </span><span class="n">Inner</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ptr</span>::<span class="n">addr_of</span><span class="o">!</span><span class="p">(</span><span class="w"> </span><span class="p">(</span><span class="o">*</span><span class="n">at_outer</span><span class="p">).</span><span class="n">inner</span><span class="w"> </span><span class="p">);</span><span class="w"></span>
<span class="w">    </span><span class="p">(</span><span class="o">*</span><span class="n">at_inner</span><span class="p">).</span><span class="n">field</span><span class="w"> </span><span class="c1">// UB!</span>
<span class="p">};</span><span class="w"></span>
</code></pre></div>
<p>So by now my opinion has moved from "this should be UB even with <code>addr_of!</code>" to "I really don't know, it's bad either way" <span aria-label="grimacing" class="emoji emoji-1f62c" role="img" title="grimacing">:grimacing:</span></p>



<a name="233005458"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/233005458" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#233005458">(Apr 03 2021 at 13:10)</a>:</h4>
<blockquote>
<p>So by now my opinion has moved from "this should be UB even with addr_of!" to "I really don't know, it's bad either way" </p>
</blockquote>
<p>hm, that is not what I was hoping for^^</p>



<a name="233006665"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/233006665" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Pointerbender <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#233006665">(Apr 03 2021 at 13:31)</a>:</h4>
<p><span class="user-mention silent" data-user-id="120791">RalfJ</span> <a href="#narrow/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref/near/232012526">said</a>:</p>
<blockquote>
<p>Currently, the Reference states that the following is UB:</p>
<blockquote>
<p>Dereferencing (using the <code>*</code> operator on) a dangling or unaligned raw pointer.</p>
</blockquote>
<p>Now that one can create unaligned raw pointers via <code>addr_of!</code>, this is probably not what we want. It means that <code>addr_of!((*ptr).field)</code> is UB when <code>ptr</code> is unaligned, even if everything is dereferencable. This is despite the fact that <code>addr_of!</code> lets you create unaligned raw pointers! That seems counter-intuitive.</p>
</blockquote>
<p>I'm following along this very interesting conversation and would like to validate whether I correctly grasp the implications of the examples that were just given. One way to make the second branch of the last example less confusing is to allow dereferencing an unaligned pointer, but this can't happen (ever? quite possibly due to the optimization potential this allows in Rust I'm assuming?) This would only make sense in the context of ptr::addr_of(_mut), because this doesn't actually dereference the given place. Am I following everything okay so far? :)</p>



<a name="233006691"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/233006691" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> NeoRaider <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#233006691">(Apr 03 2021 at 13:31)</a>:</h4>
<p>I think I'll try to write down the current rules (and where the rules are unclear) for pointer dereferencing in a Hack/CodiMD with examples.</p>



<a name="233007479"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/233007479" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> NeoRaider <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#233007479">(Apr 03 2021 at 13:45)</a>:</h4>
<p>There's a lot of subtlety in using raw pointers that can lead to UB. One way to reduce that subtlety would be to make this more explicit (requiring the programmer to assert that a pointer is aligned and does not dangle when using it in ways that require these properties... with the option to add new pointer flavors or NonNull-like wrappers that imply that a pointer is aligned and/or not dangling).</p>
<p>I guess most of this could be implemented as lints to avoid a hard breaking change (and allowing to opt out of the extra checks), but I'm not convinced that the benefits would justify the complexity of an implementation of such a feature...</p>



<a name="233009954"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/233009954" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#233009954">(Apr 03 2021 at 14:27)</a>:</h4>
<p><span class="user-mention" data-user-id="400735">@Pointerbender</span> that sounds about right... but be careful about what you mean by "dereference": do you mean the <em>place expression</em> <code>*ptr</code>, or the <em>value expression</em> <code>*ptr</code> which really is just a shorthand for <code>place2value(*ptr)</code> (but there is no explicit syntax for <code>place2value</code>... well one could use curly braces in Rust: <code>{*ptr}</code>)</p>



<a name="233011594"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/233011594" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Pointerbender <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#233011594">(Apr 03 2021 at 14:59)</a>:</h4>
<p>Thanks <span class="user-mention" data-user-id="120791">@RalfJ</span> !</p>
<blockquote>
<p>One way to make the second branch of the last example less confusing is to allow dereferencing an unaligned pointer, but this can't happen (ever? quite possibly due to the optimization potential this allows in Rust I'm assuming?)</p>
</blockquote>
<p>In this case I meant the value expression.</p>
<blockquote>
<p>This would only make sense in the context of ptr::addr_of(_mut), because this doesn't actually dereference the given place</p>
</blockquote>
<p>In this case I meant the place expression :)</p>



<a name="233011980"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/233011980" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#233011980">(Apr 03 2021 at 15:05)</a>:</h4>
<p>at least unaligned writes will be very tricky to allow... <code>*ptr = foo</code> calls <code>drop</code> on the old value stored at <code>*ptr</code> and that drop method obtaines a <em>reference</em> which must be aligned</p>



<a name="233012180"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/233012180" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> NeoRaider <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#233012180">(Apr 03 2021 at 15:08)</a>:</h4>
<p><span class="user-mention silent" data-user-id="120791">RalfJ</span> <a href="#narrow/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref/near/233011980">said</a>:</p>
<blockquote>
<p>at least unaligned writes will be very tricky to allow... <code>*ptr = foo</code> calls <code>drop</code> on the old value stored at <code>*ptr</code> and that drop method obtaines a <em>reference</em> which must be aligned</p>
</blockquote>
<p>Is assignment allowed for fields of packed structs when no raw pointers are involved? If so, how is the <code>drop()</code> handled?</p>



<a name="233012733"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/233012733" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Pointerbender <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#233012733">(Apr 03 2021 at 15:19)</a>:</h4>
<p>Looks like there is some interesting work going on in that area: <a href="https://github.com/rust-lang/rfcs/blob/master/text/1240-repr-packed-unsafe-ref.md">https://github.com/rust-lang/rfcs/blob/master/text/1240-repr-packed-unsafe-ref.md</a></p>
<blockquote>
<p>Summary<br>
Taking a reference into a struct marked repr(packed) should become unsafe, because it can lead to undefined behaviour. repr(packed) structs need to be banned from storing Drop types for this reason.</p>
</blockquote>
<p>Some additional related issues I just came accross for some extra background information:<br>
<a href="https://github.com/rust-lang/rust/issues/27060">https://github.com/rust-lang/rust/issues/27060</a><br>
<a href="https://github.com/rust-lang/rust/issues/82523">https://github.com/rust-lang/rust/issues/82523</a><br>
<a href="https://github.com/rust-lang/rust/pull/82525">https://github.com/rust-lang/rust/pull/82525</a></p>



<a name="233012751"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/233012751" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#233012751">(Apr 03 2021 at 15:19)</a>:</h4>
<p><span class="user-mention silent" data-user-id="294290">NeoRaider</span> <a href="#narrow/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref/near/233012180">said</a>:</p>
<blockquote>
<p><span class="user-mention silent" data-user-id="120791">RalfJ</span> <a href="#narrow/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref/near/233011980">said</a>:</p>
<blockquote>
<p>at least unaligned writes will be very tricky to allow... <code>*ptr = foo</code> calls <code>drop</code> on the old value stored at <code>*ptr</code> and that drop method obtaines a <em>reference</em> which must be aligned</p>
</blockquote>
<p>Is assignment allowed for fields of packed structs when no raw pointers are involved? If so, how is the <code>drop()</code> handled?</p>
</blockquote>
<p>AFAIK the data is copied to an aligned temporary location and dropped is called on that</p>



<a name="233012809"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/233012809" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Pointerbender <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#233012809">(Apr 03 2021 at 15:20)</a>:</h4>
<p>But currently storing Drop in <code>repr(packed)</code> is allowed (and UB that can be reached from safe code) it seems.</p>



<a name="233012815"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/233012815" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#233012815">(Apr 03 2021 at 15:20)</a>:</h4>
<blockquote>
<p>Looks like there is some interesting work going on in that area: <a href="https://github.com/rust-lang/rfcs/blob/master/text/1240-repr-packed-unsafe-ref.md">https://github.com/rust-lang/rfcs/blob/master/text/1240-repr-packed-unsafe-ref.md</a></p>
</blockquote>
<p>That's an ancient RFC, and it eventually lead to <code>addr_of!</code> which was recently stabilized :)</p>



<a name="233012840"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/233012840" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#233012840">(Apr 03 2021 at 15:20)</a>:</h4>
<p><span class="user-mention silent" data-user-id="400735">Pointerbender</span> <a href="#narrow/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref/near/233012809">said</a>:</p>
<blockquote>
<p>But currently storing Drop in <code>repr(packed)</code> is allowed (and UB that can be reached from safe code) it seems.</p>
</blockquote>
<p>nope there is no UB, the data is copied to a properly aligned temporary location before <code>drop</code> is called</p>



<a name="233012880"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/233012880" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Pointerbender <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#233012880">(Apr 03 2021 at 15:21)</a>:</h4>
<p>Ah! Nice <span aria-label="smile" class="emoji emoji-1f642" role="img" title="smile">:smile:</span></p>



<a name="233013091"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/233013091" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> NeoRaider <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#233013091">(Apr 03 2021 at 15:25)</a>:</h4>
<p>Hmm. Most ideas I have to solve this would lead to way too big breaking changes <span aria-label="sweat smile" class="emoji emoji-1f605" role="img" title="sweat smile">:sweat_smile:</span> </p>
<p>IMO it would be really nice if instead of a "packed" repr, we could just have an <code>Unaligned&lt;T&gt;</code> wrapper that could be used to represent fields of packed structs (with a <code>packed</code> attribute to wrap all fields of a struct in <code>Unaligned&lt;T&gt;</code>). Raw pointers could be required to be always be aligned, and raw pointers to <code>Unaligned&lt;T&gt;</code> could be used when that is not the case.</p>



<a name="233013735"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/233013735" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> NeoRaider <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#233013735">(Apr 03 2021 at 15:37)</a>:</h4>
<p>That would solve <em>so much</em> of the weirdness around packed structs and unaligned places. You could even go from a packed field to a pointer and dereference that to read/write, because you're dealing with the <code>Unaligned&lt;T&gt;</code> wrapper most of the time.</p>



<a name="233017209"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/233017209" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#233017209">(Apr 03 2021 at 16:39)</a>:</h4>
<p>Hm... interesting proposal, but it's not just backwards incompatible; the entire point of raw pointers is to not require things like alignment unless they are used -- basically like pointers in C.</p>



<a name="233017948"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/233017948" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> NeoRaider <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#233017948">(Apr 03 2021 at 16:53)</a>:</h4>
<p>If backwards compatibility weren't a concern, the last point would seem pretty weak to me. When designing raw pointers from scratch, one could decide "<code>*mut Unaligned&lt;T&gt;</code>is like a pointer in C" instead of "<code>*mut T</code>is like a pointer in C". And even in C, unaligned pointers are fairly uncommon.</p>



<a name="233018317"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/233018317" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> NeoRaider <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#233018317">(Apr 03 2021 at 17:00)</a>:</h4>
<p>Hmm, I think my proposal could be implemented as a regular crate to experiment with the idea. Pointers would become regular types like <code>NonNull&lt;T&gt;</code> in the public API  instead of something built into the language. FFI would only use the pointer types provided by the crate. Optimally, <code>*mut</code> and <code>*const</code> should be linted against when using the crate, but I guess that can wait.</p>



<a name="233036385"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/233036385" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#233036385">(Apr 03 2021 at 22:05)</a>:</h4>
<p>Since there have been a lot of non-self-contained examples (by me and others), allow me to flesh out my proposal a bit more and be explicit about the types.</p>
<ol>
<li>A <code>*const</code> place expression <code>place: T</code> is viewed as fancy syntax for the <code>*const T</code> pointer that would be written <code>addr_of!(place)</code>.</li>
<li>If <code>ptr: *const T</code>, then <code>*ptr: T</code> is a valid <code>*const</code> place of type <code>T</code>. This is a safe operation, and does not assert any properties of the pointer. This is natural given (1) since this is essentially a no-op, since <code>addr_of!(*ptr)</code> is just notation for <code>ptr</code>.</li>
<li>If <code>x: Foo</code> is a <code>*const</code> place and <code>Foo::field</code> is a field, then <code>x.field</code> is a valid <code>*const</code> place. This again does not assert any properties of the pointer, except possibly that the addition does not overflow (in which case this operation must be unsafe). The underlying pointer operation here is <code>x + offset_of!(Foo, field)</code>.</li>
<li>If <code>place: T</code> is a valid <code>*const</code> place, then <code>addr_of!(place)</code> or <code>&amp;raw place</code> is a safe operation which does not assert any properties. Again, this makes sense in light of (1) because they are two syntaxes for the same thing.</li>
<li>If <code>place: T</code> is a <code>*const</code> place referencing an aligned and dereferenceable value typed at <code>T</code>, then <code>&amp;place: &amp;T</code> is an unsafe operation that constructs a reference to <code>T</code>.</li>
<li>If <code>place: T</code> is a <code>*const</code> place referencing an aligned and dereferenceable value typed at <code>T</code>, then <code>place: T</code> (more explicitly <code>{place}</code> or <code>place2value(place)</code>) is an unsafe operation that reads a value of type <code>T</code>. This is equivalent to <code>*(&amp;place)</code> using <code>&amp;place</code> from (5).</li>
</ol>
<p>This is still a bit of a simplification, as it only treats <code>*const</code> places. There are also <code>*mut</code> places, which are the same except you can take mutable references to them as well, as well as <code>&amp;</code> places and <code>&amp;mut</code> places, for which operations (5) and (6) are safe. Whether a place is a <code>*const</code>, <code>*mut</code>, <code>&amp;</code> or <code>&amp;mut</code> place depends on the kind of pointer that was originally dereferenced in step (2) to construct the place. To support packed places, we add an additional rule to replace (3):</p>
<ol start="7">
<li>If <code>x: Foo</code> is a <code>*const</code> or <code>&amp;</code> place and <code>Foo</code> is a <code>repr(packed)</code> struct, and <code>Foo::field</code> is an unaligned field, then <code>x.field</code> is a <code>*const</code> place. This has the same safety conditions as (3). (Similarly, a <code>&amp;mut</code> place becomes a <code>*mut</code> place.)</li>
</ol>
<p>The important thing here is that even if you start from a reference place, you get a pointer place to the field, and so reading from the place or converting it to an rvalue is unsafe.</p>
<p>Consequences of this proposal in the examples are as follows:</p>
<ul>
<li>Both of Daniel's examples <a href="#narrow/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref/near/233003780">(1)</a> and <a href="#narrow/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref/near/233005249">(2)</a> are OK for both branches, and indeed desugar to exactly the same operations in each case.</li>
<li>The <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/raw.20ref.20semantics/near/232999562">equivalence</a> of <code>&amp;raw (*outer).inner.field</code> and <code>&amp;raw (*(&amp;raw (*outer).inner)).field</code> is upheld.</li>
<li>In Ralf's <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/raw.20ref.20semantics/near/232921516">example</a>, <code>&amp;raw (*null::&lt;A&gt;()).field</code> is <em>not</em> considered UB but is instead a way to construct an invalid pointer with a small integer value.</li>
<li>Regarding Ralf's <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/raw.20ref.20semantics/near/232644870">4 options</a>, this corresponds to option 3, or option 4 depending on the "except possibly" in clause (3). If the addition is allowed to overflow, then (3) can be a safe operation, but there are reportedly some LLVM performance issues with supporting this.</li>
<li>This does not match the description of <a href="https://doc.rust-lang.org/reference/behavior-considered-undefined.html">https://doc.rust-lang.org/reference/behavior-considered-undefined.html</a>, if "dereferencing a pointer" is understood as operation (2), but if it is understood as (2) + (6) then it does match. Either way, this is only making things currently undefined be defined, so it can't cause any correct code in the wild to be UB.</li>
</ul>



<a name="233450446"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/233450446" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#233450446">(Apr 07 2021 at 08:23)</a>:</h4>
<p>I don't think we should have 4 different kinds of places with 4 different rules... 1 should be enough to describe the operational semantics. (the type system surely needs to be a bit more refined, but that is not what we are talking about here.). For example:</p>
<ul>
<li>creating a place from a ptr/ref (via <code>*</code>) always succeeds, and asserts nothing.</li>
<li>offsetting a place (<code>place.field</code>, array indexing, ...) behaves like <code>ptr::offset</code> (or like <code>ptr::wrapping_offset</code>, or like a hybrid between the two that disallows overflow but allows leaving the bounds of the allocation).</li>
<li>turning a place into a raw ptr (via <code>addr_of!</code>) always succeeds and asserts nothing.</li>
<li>turning a place into a reference (via <code>&amp;</code>) asserts that the place evaluates to a pointer that is <em>valid</em> for the given reference types (this is just an instance of the general principle that each time some value of type <code>T</code> is created, it must be valid for <code>T</code>)</li>
<li>"loading" a place (place-to-value conversion) asserts that the place is aligned and does not dangle and that it stores data that is <em>valid</em> at its type; it then evaluates to that data. (again the validity constraint here is just an instance of a general principle, not a special case; in a formal operational semantics it would not be necessary to repeat this here.)</li>
</ul>
<p>(these are not the current rules, just a possible proposal)</p>



<a name="233450533"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/233450533" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#233450533">(Apr 07 2021 at 08:24)</a>:</h4>
<blockquote>
<p>addr_of!(*ptr) is just notation for ptr.</p>
</blockquote>
<p>No, it is not. It is notation for: take <code>ptr</code>, turn it into a place, and then turn that place into a raw pointer. There is no <em>a priori</em> reason that this should be a NOP, there is quite a bit going on here semantically. We could decide to define our semantics in a way that we can prove a theorem showing that the two expressions are equivalent (in value expression context), but I would not <em>start</em> with that as a presupposed axiom.<br>
You make it sound like this is true "by definition" as part of the Rust syntax/notation; that is not the case: the two expressions denote two different ASTs.</p>



<a name="233473165"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/233473165" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#233473165">(Apr 07 2021 at 11:50)</a>:</h4>
<blockquote>
<p>I don't think we should have 4 different kinds of places with 4 different rules... 1 should be enough to describe the operational semantics.</p>
</blockquote>
<p>Note that you only need 4 different kinds of places in order to satisfy the constraint that the operational semantics is completely compositional on the operations. If you define place operations all at once, treating the entire stack of projections on a local as a single thing, then it's not necessary because you can inspect the stack to determine whether you are going through references or mut references or pointers. (I'm pretty sure MIR has to do this already.)</p>



<a name="233473695"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/233473695" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#233473695">(Apr 07 2021 at 11:55)</a>:</h4>
<blockquote>
<p>turning a place into a reference (via &amp;) asserts that the place evaluates to a pointer that is valid for the given reference types (this is just an instance of the general principle that each time some value of type T is created, it must be valid for T)</p>
</blockquote>
<p>The reason for the distinction between places is for this rule: Somehow one has to determine that <code>let y = &amp;*x;</code> is safe if <code>x: &amp;T</code> but not if <code>x: *const T</code>. In the operational semantics these can be the same, but for safety checking, the intermediate place <code>*x: T</code> in these examples cannot be identical, because:</p>
<ul>
<li>If <code>*foo_ref</code> is safe and <code>*foo_ptr</code> is unsafe, then that means that <code>addr_of!(*foo_ptr)</code> will be unsafe.</li>
<li>If both <code>*foo_ref</code> and <code>*foo_ptr</code> are safe, and they have the same type, namely a place of type <code>T</code>, then <code>let y = &amp;place</code> on them cannot have different safety.</li>
</ul>



<a name="233473800"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/233473800" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#233473800">(Apr 07 2021 at 11:56)</a>:</h4>
<p>I agree that for dynamic semantics / stacked borrows, one only needs one kind of place.</p>



<a name="233474473"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/233474473" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#233474473">(Apr 07 2021 at 12:01)</a>:</h4>
<blockquote>
<p>You make it sound like this is true "by definition" as part of the Rust syntax/notation; that is not the case: the two expressions denote two different ASTs.</p>
</blockquote>
<p>It <em>is</em> true by definition in the proposed desugaring. It is different ASTs, but the same MIR. In short, the proposal eliminates the concept of "places" as distinct from "values" entirely - a place of type <code>T</code> is just a value of type <code>&amp;T</code> (or <code>*const T</code>, or another pointer type). As a result, the operation that turns a value of type <code>*const T</code> into a <code>*const</code> place of type <code>T</code> (the dereference operator), and the operation that turns a <code>*const</code> place of type <code>T</code> into a value of type <code>*const T</code> (the <code>addr_of!</code> macro), literally do nothing. They don't move, they don't copy, they don't create a new value, they have as much effect on the semantics as an extra pair of parentheses in the AST.</p>



<a name="233475321"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/233475321" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#233475321">(Apr 07 2021 at 12:07)</a>:</h4>
<p>I think for various reasons, particularly around error messages, we don't <em>literally</em> want to eliminate places from the compiler or change MIR to use values on the lhs of an assignment, but I think that this approach makes for a good mental model for answering modelling and safety questions.</p>



<a name="233937623"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/233937623" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#233937623">(Apr 10 2021 at 08:18)</a>:</h4>
<blockquote>
<p>Note that you only need 4 different kinds of places in order to satisfy the constraint that the operational semantics is completely compositional on the operations. If you define place operations all at once, treating the entire stack of projections on a local as a single thing, then it's not necessary because you can inspect the stack to determine whether you are going through references or mut references or pointers. (I'm pretty sure MIR has to do this already.)</p>
</blockquote>
<p>I think my proposal is both compositional <em>and</em> avoids "4 different kinds of places"</p>



<a name="233937644"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/233937644" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#233937644">(Apr 10 2021 at 08:18)</a>:</h4>
<blockquote>
<p>Somehow one has to determine that let y = &amp;*x; is safe if x: &amp;T but not if x: *const T</p>
</blockquote>
<p>this follows from other UB, namely that it is UB to create an invalid value, and for reference, this means it is UB to create something dangling or misaligned. no need to have an explosion of cases elsewhere.</p>



<a name="233937721"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/233937721" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#233937721">(Apr 10 2021 at 08:20)</a>:</h4>
<p><span class="user-mention silent" data-user-id="271719">Mario Carneiro</span> <a href="#narrow/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref/near/233473800">said</a>:</p>
<blockquote>
<p>I agree that for dynamic semantics / stacked borrows, one only needs one kind of place.</p>
</blockquote>
<p>wait now I am confused, didn't just your previous message argue against that? or were you not talking about the dynamic semantics there?<br>
I thought you were. specifically you asked about safety, which is defined in terms of the dynamic semantics (an operation is safe if it does not cause UB, assuming all inputs satisfy their safety invariants).</p>
<p>Maybe you were talking about the <em>syntactic</em> rules the compiler applies for its safety analysis. Those indeed might have to remember what kind of pointer a place was created from. But those rules were not the subject of this thread; this thread is primarily about the operational semantics.</p>



<a name="233937789"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/233937789" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#233937789">(Apr 10 2021 at 08:21)</a>:</h4>
<blockquote>
<p>It is true by definition in the proposed desugaring. It is different ASTs, but the same MIR.</p>
</blockquote>
<p>It is not the same MIR. Not sure what you are talking about here.^^<br>
It is the same LLVM IR, but that is not very relevant for our discussion I think.</p>



<a name="233937888"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/233937888" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#233937888">(Apr 10 2021 at 08:22)</a>:</h4>
<p><span class="user-mention silent" data-user-id="271719">Mario Carneiro</span> <a href="#narrow/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref/near/233475321">said</a>:</p>
<blockquote>
<p>I think for various reasons, particularly around error messages, we don't <em>literally</em> want to eliminate places from the compiler or change MIR to use values on the lhs of an assignment, but I think that this approach makes for a good mental model for answering modelling and safety questions.</p>
</blockquote>
<p>I disagree. I have used a mental model without places for a long while, but once I finally made the switch and understood places, many things made a lot more sense.<br>
MIR as a language inherently has places; it seems very strange to try to shoehorn a non-place semantics onto such a language. That just leads to confusion.</p>



<a name="234066323"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234066323" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Tavian Barnes <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234066323">(Apr 11 2021 at 18:38)</a>:</h4>
<p><span class="user-mention silent" data-user-id="120791">RalfJ</span> <a href="#narrow/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref/near/233017209">said</a>:</p>
<blockquote>
<p>Hm... interesting proposal, but it's not just backwards incompatible; the entire point of raw pointers is to not require things like alignment unless they are used -- basically like pointers in C.</p>
</blockquote>
<p>My understanding is that pointers in C actually do require proper alignment even if not dereferenced: <a href="https://lists.llvm.org/pipermail/llvm-dev/2016-January/094012.html">https://lists.llvm.org/pipermail/llvm-dev/2016-January/094012.html</a></p>



<a name="234074679"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234074679" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234074679">(Apr 11 2021 at 20:50)</a>:</h4>
<p><span class="user-mention" data-user-id="306504">@Tavian Barnes</span> that's fair, that is possible... we probably don't want to mimic that in Rust though, it seems like an unnecessary footgun</p>



<a name="234088972"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234088972" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234088972">(Apr 12 2021 at 00:45)</a>:</h4>
<p>By the way, that LLVM discussion brought up an <a href="https://lists.llvm.org/pipermail/llvm-dev/2016-January/094040.html">interesting data point</a> I hadn't heard of before: apparently the equivalent of <code>addr_of!(*ptr::null())</code> in C is defined behavior</p>



<a name="234089337"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234089337" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234089337">(Apr 12 2021 at 00:52)</a>:</h4>
<p>That makes some sense, as it's not doing any <code>GEP</code>ing.</p>



<a name="234089429"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234089429" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234089429">(Apr 12 2021 at 00:54)</a>:</h4>
<p><code>GEP inbounds</code> says</p>
<blockquote>
<p>The only in bounds address for a null pointer in the default address-space is the null pointer itself.</p>
</blockquote>
<p>Which would imply that in today's rust <code>addr_of!(*ptr::null().offset(0))</code> wouldn't actually hit UB in LLVM.</p>



<a name="234116861"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234116861" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234116861">(Apr 12 2021 at 07:46)</a>:</h4>
<blockquote>
<p>Which would imply that in today's rust addr_of!(*ptr::null().offset(0)) wouldn't actually hit UB in LLVM.</p>
</blockquote>
<p>It is however flagged as UB under Miri even if we ignore the UB due to <code>*null</code>... and rightly so, I think: there is a very nice way to define "inbounds-offset" <em>without</em> introducing a whole new concept to the memory model: <code>ptr.offset(i)</code> is allowed if <code>ptr .. ptr+i</code> is dereferencable (for positive i) / if <code>ptr+i .. ptr</code> is dereferencable (for negative i).</p>



<a name="234116963"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234116963" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234116963">(Apr 12 2021 at 07:47)</a>:</h4>
<p>LLVM is very unclear about when exactly offset=0 is allowed for GEPi</p>



<a name="234117145"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234117145" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234117145">(Apr 12 2021 at 07:49)</a>:</h4>
<p>for example, I once asked them if this is allowed for pointers that have been <code>free</code>d (in contrast to pointers created by casting from an integer -- both pointers dangle in a sense, but in different ways), and I think the answer I got is "no" but I wasn't sure if my question was even properly understood.</p>



<a name="234117352"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234117352" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234117352">(Apr 12 2021 at 07:51)</a>:</h4>
<p><span class="user-mention silent" data-user-id="271719">Mario Carneiro</span> <a href="#narrow/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref/near/234088972">said</a>:</p>
<blockquote>
<p>By the way, that LLVM discussion brought up an <a href="https://lists.llvm.org/pipermail/llvm-dev/2016-January/094040.html">interesting data point</a> I hadn't heard of before: apparently the equivalent of <code>addr_of!(*ptr::null())</code> in C is defined behavior</p>
</blockquote>
<p>is it defined behavior in the LLVM IR generated by clang, or in the C spec?</p>



<a name="234117625"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234117625" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234117625">(Apr 12 2021 at 07:53)</a>:</h4>
<p>hm, C says</p>
<blockquote>
<p>If the operand is the result of a unary * operator,<br>
neither that operator nor the &amp; operator is evaluated and the result is as if both were<br>
omitted, except that the constraints on the operators still apply and the result is not an lvalue.</p>
</blockquote>
<p>not sure what "constraints" this refers to, but that might include "no NULL ptrs"?<br>
(also, this is a horrible definition IMO -- the behavior of <code>&amp;expr</code> should depend only on the result of evaluating <code>expr</code>, not on its syntactic shape... this is non-compositional <em>shiver</em>)</p>



<a name="234135612"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234135612" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234135612">(Apr 12 2021 at 10:30)</a>:</h4>
<p>Oh, and while the example on the mailing list was:</p>
<div class="codehilite" data-code-language="C"><pre><span></span><code>  <span class="kt">int</span> <span class="o">*</span><span class="n">foo</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
  <span class="kt">int</span> <span class="o">*</span><span class="n">bar</span> <span class="o">=</span> <span class="o">&amp;*</span><span class="n">foo</span><span class="p">;</span>
</code></pre></div>
<p>of course</p>
<div class="codehilite" data-code-language="C"><pre><span></span><code>  <span class="kt">int</span> <span class="o">*</span><span class="n">bar</span> <span class="o">=</span> <span class="o">&amp;*</span><span class="mi">0</span><span class="p">;</span>
</code></pre></div>
<p>is a compile error. How's that for non-compositional?</p>



<a name="234136256"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234136256" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234136256">(Apr 12 2021 at 10:36)</a>:</h4>
<p>Actually I take it back, that doesn't compile because of type inference reasons. I'm sure there is another place in the grammar where passing NULL directly is a compile error but passing it in a variable is defined, but I can't remember the context</p>



<a name="234137988"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234137988" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234137988">(Apr 12 2021 at 10:52)</a>:</h4>
<p><span class="user-mention silent" data-user-id="120791">RalfJ</span> <a href="#narrow/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref/near/234116861">said</a>:</p>
<blockquote>
<blockquote>
<p>Which would imply that in today's rust addr_of!(*ptr::null().offset(0)) wouldn't actually hit UB in LLVM.</p>
</blockquote>
<p>It is however flagged as UB under Miri even if we ignore the UB due to <code>*null</code>... and rightly so, I think: there is a very nice way to define "inbounds-offset" <em>without</em> introducing a whole new concept to the memory model: <code>ptr.offset(i)</code> is allowed if <code>ptr .. ptr+i</code> is dereferencable (for positive i) / if <code>ptr+i .. ptr</code> is dereferencable (for negative i).</p>
</blockquote>
<p>I'm not sure I follow this. Using your dereferenceable definition, we need an empty region to be dereferenceable so <code>ptr.offset(0)</code> should always be inbounds, so why is it flagged as UB?</p>



<a name="234138168"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234138168" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234138168">(Apr 12 2021 at 10:53)</a>:</h4>
<p>empty regions are not always dereferencable :)</p>



<a name="234138232"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234138232" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234138232">(Apr 12 2021 at 10:54)</a>:</h4>
<p>oof</p>



<a name="234138250"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234138250" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234138250">(Apr 12 2021 at 10:54)</a>:</h4>
<p>don't think of <code>ptr...ptr2</code> as a set</p>



<a name="234138267"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234138267" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234138267">(Apr 12 2021 at 10:54)</a>:</h4>
<p>more like, a <code>start, len</code> pair</p>



<a name="234138336"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234138336" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234138336">(Apr 12 2021 at 10:55)</a>:</h4>
<p>see e.g. the notes at <a href="https://doc.rust-lang.org/nightly/std/ptr/index.html">https://doc.rust-lang.org/nightly/std/ptr/index.html</a> for validity with size 0</p>



<a name="234138360"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234138360" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234138360">(Apr 12 2021 at 10:55)</a>:</h4>
<p>and I guess you want all pointer values in the range (inclusive) to be within the range of an allocation or one-past?</p>



<a name="234138399"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234138399" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234138399">(Apr 12 2021 at 10:55)</a>:</h4>
<p>roughly speaking, <code>ptr...ptr+0</code> is dereferencable if</p>
<ul>
<li>either <code>ptr</code> is a non-zero <em>integer</em> ("ptr obtained from an int literal")</li>
<li>or <code>ptr</code> is inbounds of a live allocation</li>
</ul>



<a name="234138473"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234138473" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234138473">(Apr 12 2021 at 10:56)</a>:</h4>
<p>(this is using the "logical/physical" model of pointers, like in <a href="https://people.mpi-sws.org/~jung/twinsem/twinsem.pdf">this paper</a> or like in Miri)</p>



<a name="234138553"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234138553" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234138553">(Apr 12 2021 at 10:57)</a>:</h4>
<p>Are those alternative definitions, or one disjunctive definition? Because it seems like the first one subsumes the other</p>



<a name="234138558"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234138558" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234138558">(Apr 12 2021 at 10:57)</a>:</h4>
<p>these are the same rules as the ones for then <code>*ptr</code> is allowed for <code>ptr: *const ()</code></p>



<a name="234138578"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234138578" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234138578">(Apr 12 2021 at 10:57)</a>:</h4>
<p><span class="user-mention silent" data-user-id="271719">Mario Carneiro</span> <a href="#narrow/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref/near/234138553">said</a>:</p>
<blockquote>
<p>Are those alternative definitions, or one disjunctive definition? Because it seems like the first one subsumes the other</p>
</blockquote>
<p>it is a disjunctive definition</p>



<a name="234138597"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234138597" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234138597">(Apr 12 2021 at 10:57)</a>:</h4>
<p>and neither branch subsumes the other</p>



<a name="234138618"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234138618" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234138618">(Apr 12 2021 at 10:57)</a>:</h4>
<p>remember that ptrs have provenance</p>



<a name="234138628"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234138628" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234138628">(Apr 12 2021 at 10:57)</a>:</h4>
<p>so they are not, in general, integers</p>



<a name="234138703"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234138703" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234138703">(Apr 12 2021 at 10:58)</a>:</h4>
<p>Oh, "integer" is the key word</p>



<a name="234138768"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234138768" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234138768">(Apr 12 2021 at 10:59)</a>:</h4>
<p>yeah</p>



<a name="234138852"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234138852" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234138852">(Apr 12 2021 at 11:00)</a>:</h4>
<p>this model unfortunately runs into ambiguity when you ask too tricky questions around ptr-int-ptr roundtrips... I see various ways to resolve them but sadly the LLVM LangRef does not even acknowledge the existence of this problem so it's unclear which of the resolutions are LLVM-compatible^^</p>



<a name="234138932"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234138932" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234138932">(Apr 12 2021 at 11:00)</a>:</h4>
<p>And these rules are taken from the GEPi docs?</p>



<a name="234138963"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234138963" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234138963">(Apr 12 2021 at 11:00)</a>:</h4>
<p>ha, I wish</p>



<a name="234139006"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234139006" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234139006">(Apr 12 2021 at 11:00)</a>:</h4>
<p>perhaps "decoded" is a better word :P</p>



<a name="234139057"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234139057" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234139057">(Apr 12 2021 at 11:01)</a>:</h4>
<p>"inspired by" ;)</p>



<a name="234139092"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234139092" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234139092">(Apr 12 2021 at 11:01)</a>:</h4>
<p>or "a possible formal extrapolation of" the GEPi docs</p>



<a name="234139243"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234139243" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234139243">(Apr 12 2021 at 11:02)</a>:</h4>
<p>I tried to confirm with the llvm devs about what their intended interpretation is, but I think I failed to even get across the question... the question only makes sense once you accept that ptrs have provenance and are not modeled by an underlying integer address, and that is not something LLVM officially acknowledges</p>



<a name="234139344"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234139344" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234139344">(Apr 12 2021 at 11:03)</a>:</h4>
<p>basically we first need a more precise def.n of "what even is a pointer in LLVM" and <em>then</em> we can ask such questions for different kinds of pointers</p>



<a name="234139405"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234139405" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234139405">(Apr 12 2021 at 11:04)</a>:</h4>
<p>Do you know how to get LLVM to use <code>offset</code> to derive inbounds of a pointer that is not loaded?</p>



<a name="234139517"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234139517" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234139517">(Apr 12 2021 at 11:05)</a>:</h4>
<p>Since I guess that's the main problem with using GEPi in <code>addr_of!((*ptr).field)</code> if we want to follow the model we talked about above</p>



<a name="234505672"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234505672" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234505672">(Apr 14 2021 at 14:15)</a>:</h4>
<p>you mean, making LLVM cause undesired effects that way? no, I am not good at that game^^</p>



<a name="234505791"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234505791" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234505791">(Apr 14 2021 at 14:16)</a>:</h4>
<p>in fact it might not even be sound for LLVM to do that -- what if that pointer points to volatile memory?</p>



<a name="234505878"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234505878" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234505878">(Apr 14 2021 at 14:16)</a>:</h4>
<p>IOW, I am not sure if LLVM reverses the right to insert spurious reads based on <code>GEPi</code>, and if it did that could be... problematic</p>



<a name="234977947"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234977947" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234977947">(Apr 17 2021 at 10:19)</a>:</h4>
<p>cc <span class="user-group-mention" data-user-group-id="1162">@WG-mir-opt</span></p>



<a name="234978115"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234978115" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234978115">(Apr 17 2021 at 10:21)</a>:</h4>
<p><span class="user-mention" data-user-id="271719">@Mario Carneiro</span> can you post a summary of the discussion here? Is the suggestion a lowering on mir without datastructure changes?</p>



<a name="234978204"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234978204" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234978204">(Apr 17 2021 at 10:22)</a>:</h4>
<p>If it is, maybe we can add a way for codegen backends to inject mir optimizations into the optimizedmir query</p>



<a name="234978435"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234978435" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234978435">(Apr 17 2021 at 10:26)</a>:</h4>
<p>from my perspective the summary is that we found a way to describe things compositionally <em>with</em> places that works sufficiently well that it's not worth turning everything upside down^^</p>



<a name="234978548"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234978548" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234978548">(Apr 17 2021 at 10:28)</a>:</h4>
<p>We discussed a few possibilities, some of which have more changes to MIR than others. Option 1 is summarized in <a href="#narrow/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref/near/233450446">this post</a> with an <a href="#narrow/stream/213817-t-lang/topic/MIR.20without.20places/near/234035925">addendum</a> for packed places. This should not require any changes to MIR, but does make some expressions defined that are currently UB, notably the place expression <code>*ptr::null()</code> and offsets from it, which is observable via the <code>addr_of!</code> macro. I believe that some codegen needs to be adjusted to make this sound wrt LLVM's semantics.</p>
<p>Option 2 is summarized in <a href="#narrow/stream/213817-t-lang/topic/MIR.20without.20places/near/234038595">this post</a> and amounts to adding type information to the <code>place2value</code> operation in MIR. Ralf opened <a href="https://github.com/rust-lang/rust/issues/63085#issuecomment-817330147">an issue</a> for this. There are some open questions about what strong typing for place alignment means in the context of unsized structs, and I'm not sure about the details here.</p>



<a name="234979011"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234979011" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234979011">(Apr 17 2021 at 10:37)</a>:</h4>
<p>Personally, I would be interested in pushing option 1, which has material effect on the spec, and leaving investigation of option 2 (which should have no user visible effects) until later</p>



<a name="234981707"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234981707" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234981707">(Apr 17 2021 at 11:25)</a>:</h4>
<p>So I poked around in the codegen_ssa code and here's my recommendation for how to implement option 1:</p>
<ul>
<li><code>PlaceRef</code> gets an additional field <code>inbounds: bool</code> that is true when the place is derived from a reference or if we know for some reason that the place is dereferenceable and valid (which is mostly not true for pointers).</li>
<li><code>PlaceRef::project_index</code> will use <code>gep</code> instead of <code>inbounds_gep</code> when <code>inbounds</code> is false.</li>
<li><code>PlaceRef::deref</code> will set <code>inbounds</code> to <code>true</code> if it is dereferencing a <code>Box&lt;T&gt;</code> or <code>&amp;T</code> and <code>false</code> for <code>*T</code></li>
</ul>
<p>Is this a reasonable plan <span class="user-mention" data-user-id="120791">@RalfJ</span> <span class="user-mention" data-user-id="124288">@oli</span> ? I haven't actually worked with codegen directly so I might be missing something.</p>
<p>This should cover correctness, but there is potential for a big performance regression due to the use of non-inbounds GEP around pointers. In order to optimize this, we need to keep track of pointers that have been or will be dereferenced, and the result of the analysis needs to be stored in MIR somehow so that codegen will pick it up. Note that a partial read of a pointer is not sufficient, for example:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">fn</span> <span class="nf">foo</span><span class="p">(</span><span class="n">x</span>: <span class="o">*</span><span class="k">const</span><span class="w"> </span><span class="p">(</span><span class="kt">u8</span><span class="p">,</span><span class="w"> </span><span class="kt">u8</span><span class="p">))</span><span class="w"> </span>-&gt; <span class="o">*</span><span class="k">const</span><span class="w"> </span><span class="kt">u8</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">addr_of</span><span class="o">!</span><span class="p">((</span><span class="o">*</span><span class="n">x</span><span class="p">).</span><span class="mi">1</span><span class="p">)</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
<span class="k">fn</span> <span class="nf">bar</span><span class="p">(</span><span class="n">x</span>: <span class="o">*</span><span class="k">const</span><span class="w"> </span><span class="p">(</span><span class="kt">u8</span><span class="p">,</span><span class="w"> </span><span class="kt">u8</span><span class="p">))</span><span class="w"> </span>-&gt; <span class="kt">u8</span> <span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">unsafe</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="p">(</span><span class="o">*</span><span class="n">x</span><span class="p">).</span><span class="mi">1</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>We are not allowed to use GEPi in these examples under the revised rules. But we can in these versions:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">fn</span> <span class="nf">foo</span><span class="p">(</span><span class="n">x</span>: <span class="o">*</span><span class="k">const</span><span class="w"> </span><span class="p">(</span><span class="kt">u8</span><span class="p">,</span><span class="w"> </span><span class="kt">u8</span><span class="p">))</span><span class="w"> </span>-&gt; <span class="o">*</span><span class="k">const</span><span class="w"> </span><span class="kt">u8</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">_x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">unsafe</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="o">*</span><span class="n">x</span><span class="w"> </span><span class="p">};</span><span class="w"></span>
<span class="w">    </span><span class="n">addr_of</span><span class="o">!</span><span class="p">((</span><span class="o">*</span><span class="n">x</span><span class="p">).</span><span class="mi">1</span><span class="p">)</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
<span class="k">fn</span> <span class="nf">bar</span><span class="p">(</span><span class="n">x</span>: <span class="o">*</span><span class="k">const</span><span class="w"> </span><span class="p">(</span><span class="kt">u8</span><span class="p">,</span><span class="w"> </span><span class="kt">u8</span><span class="p">))</span><span class="w"> </span>-&gt; <span class="kt">u8</span> <span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">_x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">unsafe</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="o">&amp;*</span><span class="n">x</span><span class="w"> </span><span class="p">};</span><span class="w"></span>
<span class="w">    </span><span class="k">unsafe</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="p">(</span><span class="o">*</span><span class="n">x</span><span class="p">).</span><span class="mi">1</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>I don't know how relevant it is to detect and optimize this. Probably we won't have enough information about most pointers to use GEPi, but perhaps it is sufficient to just use GEPi for references on the assumption that raw pointer programs are rare and those that use raw pointer indexing expressions like <code>addr_of!((*x).1)</code> are doing so for a reason.</p>



<a name="234984230"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234984230" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234984230">(Apr 17 2021 at 12:08)</a>:</h4>
<p>Uncelar to me how <code>gep</code> vs <code>gepi</code> changes anything here.</p>



<a name="234984326"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234984326" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234984326">(Apr 17 2021 at 12:10)</a>:</h4>
<p>ah, because null pointer is presumed to not be pointing at an allocated object, okay sure.</p>



<a name="234984626"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234984626" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234984626">(Apr 17 2021 at 12:14)</a>:</h4>
<blockquote>
<p>Is this a reasonable plan @RalfJ @oli ? I haven't actually worked with codegen directly so I might be missing something.</p>
</blockquote>
<p>This sounds like a reasonable plan to implement "place projections behave like <code>wrapping_offset</code>"; but I am not sure if that is a reasonable next step to take. I'd probably, at least for now, let them behave like <code>offset</code>. This requires no changes in the codegen backend. There is still room for having less UB there than we currently do, i.e., there are some interesting language (and Miri) changes we can do first before proposing things that would require codegen changes.</p>



<a name="234984727"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234984727" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234984727">(Apr 17 2021 at 12:16)</a>:</h4>
<p>(I will also note that this discussion is much more on-topic for <a href="#narrow/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref">the original thread</a> than for this one that spawned-off to discuss how to have compositional semantics for place-based languages.)</p>



<a name="234986937"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234986937" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234986937">(Apr 17 2021 at 12:58)</a>:</h4>
<p>I will relocate today's portion of the thread to the other thread. The discussion was sort of happening simultaneously on both threads and I agree the summary is more relevant to "derefing NULL"</p>



<a name="234987356"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234987356" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234987356">(Apr 17 2021 at 13:05)</a>:</h4>
<blockquote>
<p>I'd probably, at least for now, let them behave like <code>offset</code>.</p>
</blockquote>
<p>I think we need more dynamic state in place results in order to achieve <code>offset</code>-like behavior for reads and writes without asserting validity of anything in <code>addr_of!</code>. For example, a place collects a region that should be inbounds, and a read/write to the place actually makes the assertion, while <code>addr_of!</code> discards it</p>



<a name="234987481"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234987481" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234987481">(Apr 17 2021 at 13:07)</a>:</h4>
<p>It's a bit of weird action at a distance though that <code>(*x)[12] = 1</code> asserts that <code>(*x)[0]</code> is valid</p>



<a name="234987576"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234987576" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234987576">(Apr 17 2021 at 13:08)</a>:</h4>
<p>it makes a lot more sense to me that this should only assert validity of <code>&amp;(*x)[12]</code> itself</p>



<a name="234987723"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234987723" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234987723">(Apr 17 2021 at 13:11)</a>:</h4>
<p><span class="user-mention silent" data-user-id="271719">Mario Carneiro</span> <a href="#narrow/stream/213817-t-lang/topic/New.20lint.20for.20deref'ing.20NULL.20pointers/near/234987356">said</a>:</p>
<blockquote>
<blockquote>
<p>I'd probably, at least for now, let them behave like <code>offset</code>.</p>
</blockquote>
<p>I think we need more dynamic state in place results in order to achieve <code>offset</code>-like behavior for reads and writes without asserting validity of anything in <code>addr_of!</code>. For example, a place collects a region that should be inbounds, and a read/write to the place actually makes the assertion, while <code>addr_of!</code> discards it</p>
</blockquote>
<p>Absolutely -- <em>if</em> <code>addr_of!</code> should assert no validity, we need to do more</p>



<a name="234987726"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234987726" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234987726">(Apr 17 2021 at 13:11)</a>:</h4>
<p>what I am saying is, for now, let's just be okay with <code>addr_of!</code> still sometiems asserting some things</p>



<a name="234987733"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234987733" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234987733">(Apr 17 2021 at 13:11)</a>:</h4>
<p>specifically, <code>addr_of!((*p).field)</code> asserting "inbounds" for this arithmetic</p>



<a name="234987776"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234987776" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234987776">(Apr 17 2021 at 13:12)</a>:</h4>
<p>(FWIW; the <code>addr_of!</code> isn't asserting anything here, it is the place projection that does, but I think this is what you meant)</p>



<a name="234987806"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234987806" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234987806">(Apr 17 2021 at 13:13)</a>:</h4>
<p>basically what I am saying is, there is a large gap between the current rules and the rules you are proposing. instead of trying to bridge that entire gap at once, let's do it step-by-step. that will also make it easier to figure out how far along this journey we still have consensus.</p>



<a name="234987838"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234987838" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234987838">(Apr 17 2021 at 13:13)</a>:</h4>
<p><a href="#narrow/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref/near/233450446">this post</a> that you linked to does <em>not</em> say that place expressions in <code>addr_of!</code> do not assert any validity -- note that using <code>offset!</code> is mentioned as the "main" option with the alternatives being parenthesized.</p>



<a name="234987925"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234987925" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234987925">(Apr 17 2021 at 13:15)</a>:</h4>
<p>I think the spec suggested in the "main" part of that post (not one of the parenthetical alternaatives) is a very reasonable first step, and I think chances are high we can find conensus for it. it <em>already</em> matches current codegen, so there is a potential loss of future optimizations but no loss compared to what we do now.</p>



<a name="234988011"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234988011" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234988011">(Apr 17 2021 at 13:16)</a>:</h4>
<p>going further and actually changing codegen to not have "inbounds" will be much harder to achieve consensus for I think, and will require work to measure performance impact and things like that.</p>



<a name="234989123"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234989123" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234989123">(Apr 17 2021 at 13:36)</a>:</h4>
<p><span class="user-mention silent" data-user-id="120791">RalfJ</span> <a href="#narrow/stream/213817-t-lang/topic/New.20lint.20for.20deref'ing.20NULL.20pointers/near/234987838">said</a>:</p>
<blockquote>
<p><a href="#narrow/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref/near/233450446">this post</a> that you linked to does <em>not</em> say that place expressions in <code>addr_of!</code> do not assert any validity -- note that using <code>offset!</code> is mentioned as the "main" option with the alternatives being parenthesized.</p>
</blockquote>
<p>I was aiming for this version:</p>
<blockquote>
<p>or like a hybrid between the two that disallows overflow but allows leaving the bounds of the allocation</p>
</blockquote>
<p>although the proposed codegen would allow the fully safe wrapping version as well</p>



<a name="234989150"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234989150" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234989150">(Apr 17 2021 at 13:37)</a>:</h4>
<p>I have to keep reminding myself what <code>ptr::offset</code> actually does because it has bewildering UB rules</p>



<a name="234989247"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234989247" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234989247">(Apr 17 2021 at 13:39)</a>:</h4>
<p><span class="user-mention silent" data-user-id="120791">RalfJ</span> <a href="#narrow/stream/213817-t-lang/topic/New.20lint.20for.20deref'ing.20NULL.20pointers/near/234988011">said</a>:</p>
<blockquote>
<p>going further and actually changing codegen to not have "inbounds" will be much harder to achieve consensus for I think, and will require work to measure performance impact and things like that.</p>
</blockquote>
<p>Yes, that's my hope for this "next step": get some data on what we stand to lose by using GEP</p>



<a name="234989643"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234989643" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234989643">(Apr 17 2021 at 13:46)</a>:</h4>
<p><span class="user-mention silent" data-user-id="120791">RalfJ</span> <a href="#narrow/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref/near/234987925">said</a>:</p>
<blockquote>
<p>I think the spec suggested in the "main" part of that post (not one of the parenthetical alternaatives) is a very reasonable first step, and I think chances are high we can find conensus for it. it <em>already</em> matches current codegen, so there is a potential loss of future optimizations but no loss compared to what we do now.</p>
</blockquote>
<p>In what way does it differ from the status quo? Is it just a lack of specification in this area? The only thing I can think of is that we can remove <code>*NULL</code> places from the list of UB things in the reference</p>



<a name="234990642"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234990642" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234990642">(Apr 17 2021 at 14:05)</a>:</h4>
<blockquote>
<p>In what way does it differ from the status quo? Is it just a lack of specification in this area?</p>
</blockquote>
<p>There's no "lack of specification". Our specification is quite clear about this being UB: <code>addr_of!(*NULL)</code>.<br>
So the proposal differs from the status quo in that that code would not be UB any more.</p>



<a name="234990712"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234990712" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234990712">(Apr 17 2021 at 14:06)</a>:</h4>
<p>UB doesn't mean "this isn't yet specified" or anything like that. It means "the Abstract Machine that your Rust programs -- <em>all</em> Rust programs -- run on will stop hard with an error when you do this. implementations of the Abstract Machine are <em>not</em> required to detect this error situation and may instead assume it will never occur."<br>
(I know you know this, but your statements IMO don't to it justice, hence why I am trying to make it very clear here.)</p>



<a name="234990773"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234990773" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234990773">(Apr 17 2021 at 14:07)</a>:</h4>
<p>any change to the Abstract Machine must be done with great care since it is the bedrock on which all attempts to precisely capture the behavior of Rust programs (and notions such as "safety", that are really important for Rust) are built</p>



<a name="234990834"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234990834" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234990834">(Apr 17 2021 at 14:08)</a>:</h4>
<p>so I don't entirely understand why you seem to take such a cavalier attitude to changing the spec to make some things not UB any more (spec-only changes) and already plan ahead for the next step -- maybe let's do step 1 before we do step 2, to avoid stumbling over our own feet?</p>



<a name="234990947"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234990947" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234990947">(Apr 17 2021 at 14:10)</a>:</h4>
<blockquote>
<p>The only thing I can think of is that we can remove *NULL places from the list of UB things in the reference</p>
</blockquote>
<p>"*NULL places" are not mentioned in <a href="https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html">the UB list</a></p>



<a name="234991044"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234991044" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234991044">(Apr 17 2021 at 14:12)</a>:</h4>
<p>and the change I am talking about can <em>not</em> be achieved by simply removing the bullet point "Evaluating a dereference expression (<code>*expr</code>) on a raw pointer that is dangling or unaligned, even in place expression context (e.g. addr_of!(<code>&amp;*expr</code>)).". If you just remove that point, the resulting Abstract Machine spec is not implementable efficiently on real hardware. We need to <em>replace</em> it with something else, something more complicated, something <a href="#narrow/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref/near/233450446">like this</a>. Doing that will require work that is not done yet: writing everything up more precisely and going through the consensus process to ensure that everyone agrees that this makes sense.</p>



<a name="234991316"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234991316" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234991316">(Apr 17 2021 at 14:17)</a>:</h4>
<p><span class="user-mention silent" data-user-id="120791">RalfJ</span> <a href="#narrow/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref/near/234990834">said</a>:</p>
<blockquote>
<p>so I don't entirely understand why you seem to take such a cavalier attitude to changing the spec to make some things not UB any more (spec-only changes) and already plan ahead for the next step -- maybe let's do step 1 before we do step 2, to avoid stumbling over our own feet?</p>
</blockquote>
<p>Well, as you are aware, we shouldn't just be crossing out items on a list of UB, we should have a full internally consistent theory to explain what is and isn't UB. The rules I am aiming for do that, but they have codegen impact because they don't validate the GEPi stuff. I'm not sure I would call that cavalier: there are still many steps ahead, in particular an RFC and a test for performance impact.</p>



<a name="234991431"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234991431" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234991431">(Apr 17 2021 at 14:19)</a>:</h4>
<p>I agree that the version that uses <code>offset</code> is a smaller change, and my question was what exactly the change is, as in, what you would put in an RFC or other document to explain what we have now, and what will be different with the proposal. As far as I can tell the only effect is that <code>addr_of!(*ptr)</code> becomes unconditionally defined</p>



<a name="234991529"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234991529" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234991529">(Apr 17 2021 at 14:20)</a>:</h4>
<p>what I meant by "cavalier" is <a href="#narrow/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref/near/234989643">this message</a> which sounds like the first step I am proposing would be not much of a change, when I think it is -- it requires talking much more explicitly than we currently do about places vs values</p>



<a name="234991546"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234991546" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234991546">(Apr 17 2021 at 14:21)</a>:</h4>
<p><span class="user-mention silent" data-user-id="120791">RalfJ</span> <a href="#narrow/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref/near/234991044">said</a>:</p>
<blockquote>
<p>and the change I am talking about can <em>not</em> be achieved by simply removing the bullet point "Evaluating a dereference expression (<code>*expr</code>) on a raw pointer that is dangling or unaligned, even in place expression context (e.g. addr_of!(<code>&amp;*expr</code>)).". If you just remove that point, the resulting Abstract Machine spec is not implementable efficiently on real hardware.</p>
</blockquote>
<p>I assume we would not be crossing that out but rather restoring it to what I originally interpreted that point as: "dereferencing a null pointer is UB" meaning <code>place2value(*NULL)</code></p>



<a name="234991585"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234991585" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234991585">(Apr 17 2021 at 14:21)</a>:</h4>
<p>I would recommend to push that through to the end before attempting to then relax these rules further, I think that is easier to explain and less likely to lead to opposition (certainly from my side -- I am totally onboard with step 1 and very unsure about step 2)</p>



<a name="234991635"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234991635" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234991635">(Apr 17 2021 at 14:22)</a>:</h4>
<p>in terms of observable changes of behavior, another change would be that <code>addr_of!((*unaligned_ptr).field)</code> would not be UB any more for a dereferencable unaligned ptr</p>



<a name="234991654"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234991654" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234991654">(Apr 17 2021 at 14:22)</a>:</h4>
<p><del>I'm fine with that but I would like to see the diff between your proposal and the status quo explained</del></p>



<a name="234991673"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234991673" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234991673">(Apr 17 2021 at 14:22)</a>:</h4>
<p>also, if <code>ptr: *const (i32, i32)</code> is dereferencable for 4 bytes but not for 8 bytes, then currently <code>addr_of!((*ptr).1)</code> is UB; that would not be the case any more either</p>



<a name="234991701"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234991701" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234991701">(Apr 17 2021 at 14:23)</a>:</h4>
<p>... I am trying to think of more cases but I think this covers the broad categories of things that would change</p>



<a name="234991744"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234991744" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234991744">(Apr 17 2021 at 14:24)</a>:</h4>
<p>oof, that last one doesn't sound great</p>



<a name="234991769"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234991769" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234991769">(Apr 17 2021 at 14:24)</a>:</h4>
<p>why?</p>



<a name="234991794"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234991794" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234991794">(Apr 17 2021 at 14:25)</a>:</h4>
<p>because <code>addr_of!((*ptr).1)</code> asserts that all 8 bytes are dereferenceable</p>



<a name="234991818"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234991818" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234991818">(Apr 17 2021 at 14:25)</a>:</h4>
<p>so we have some left bias here</p>



<a name="234991833"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234991833" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234991833">(Apr 17 2021 at 14:26)</a>:</h4>
<p>in fact, if we don't know the order of fields in a struct we might not even be able to tell whether it's UB or not (by looking at the code)</p>



<a name="234991916"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234991916" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234991916">(Apr 17 2021 at 14:27)</a>:</h4>
<p>oh actually my example was wrong... let me fix... done</p>



<a name="234991941"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234991941" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234991941">(Apr 17 2021 at 14:27)</a>:</h4>
<p><code>addr_of!((*ptr).0)</code> does an offset by 0. this, uh asserts something but not a lot^^</p>



<a name="234991982"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234991982" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234991982">(Apr 17 2021 at 14:28)</a>:</h4>
<p><code>addr_of!((*ptr).1)</code> does an offset by 4 which is easy, it just asserts that those 4 bytes all lie in the same live allocation</p>



<a name="234992002"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234992002" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234992002">(Apr 17 2021 at 14:28)</a>:</h4>
<p>Maybe a better example: <code>(*ptr).1 = 1</code> asserts validity of all 8 bytes, <code>(*ptr).0 = 1</code> asserts validity of only the left half</p>



<a name="234992010"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234992010" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234992010">(Apr 17 2021 at 14:28)</a>:</h4>
<p>offset-by-0 is currently in Miri defined to be valid <em>unless</em> one of these conditions is met:</p>
<ul>
<li>the ptr is NULL</li>
<li>the ptr has the provenance of some allocation and either that allocation no longer exists or the ptr is out-of-bounds of that allocation</li>
</ul>



<a name="234992040"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234992040" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234992040">(Apr 17 2021 at 14:29)</a>:</h4>
<p><span class="user-mention silent" data-user-id="271719">Mario Carneiro</span> <a href="#narrow/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref/near/234992002">said</a>:</p>
<blockquote>
<p>Maybe a better example: <code>(*ptr).1 = 1</code> asserts validity of all 8 bytes, <code>(*ptr).0 = 1</code> asserts validity of only the left half</p>
</blockquote>
<p>neither asserts any validity, but if you mean dereferencability ("non-dangling") then yes</p>



<a name="234992100"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234992100" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234992100">(Apr 17 2021 at 14:30)</a>:</h4>
<p>("validity" has a specific meaning already in the context of rust UB, let's not overload that)</p>



<a name="234992121"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234992121" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234992121">(Apr 17 2021 at 14:30)</a>:</h4>
<p>is it safe to substitute "validity at <code>MaybeUninit&lt;[u8; N]&gt;</code>" for "dereferenceability"</p>



<a name="234992171"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234992171" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234992171">(Apr 17 2021 at 14:31)</a>:</h4>
<p>that doesn't make a lot of sense as validity is a property that is defined <em>on the bytes after they were loaded from memory</em>, whereas here we are talking about whether such bytes even exist. i..e., your statement doesn't type-check.</p>



<a name="234992230"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234992230" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234992230">(Apr 17 2021 at 14:32)</a>:</h4>
<p>dereferenceability is a predicate on a ptr or address; validity is a predicate on a type and a list of bytes</p>



<a name="234992241"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234992241" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234992241">(Apr 17 2021 at 14:32)</a>:</h4>
<p>ok so  "validity at <code>&amp;MaybeUninit&lt;[u8; N]&gt;</code>" then?</p>



<a name="234992297"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234992297" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234992297">(Apr 17 2021 at 14:33)</a>:</h4>
<p>yeah I was about to suggest that^^ but then I realized that we have aliasing rules and while I'd say those are not part of validity but something separate... it might be better to just use a different word^^</p>



<a name="234992302"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234992302" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234992302">(Apr 17 2021 at 14:33)</a>:</h4>
<p>ah nevermind I'll just live with it</p>



<a name="234992308"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234992308" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234992308">(Apr 17 2021 at 14:33)</a>:</h4>
<p>just making sure there isn't anything extra loaded in that word</p>



<a name="234992343"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234992343" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234992343">(Apr 17 2021 at 14:34)</a>:</h4>
<p>anyway I get what you mean, I just think it's important that we have precise terminology and agree on what it means. we are discussing subtle technical matters here.</p>



<a name="234992434"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234992434" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234992434">(Apr 17 2021 at 14:35)</a>:</h4>
<p>does dereferencability say anything about whether there is a conflicting borrow to the bytes?</p>



<a name="234992953"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234992953" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234992953">(Apr 17 2021 at 14:44)</a>:</h4>
<p>no... I dont think it should, and in Miri it doesnt</p>



<a name="234993000"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234993000" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234993000">(Apr 17 2021 at 14:45)</a>:</h4>
<p>we could avoid this "left-leaning" by replacing the rule for place projections to instead say something like</p>
<ul>
<li>a place projection on place <code>p</code> is UB if <code>p</code> is dangling (using the type of <code>p</code> to determine the relevant size of the memory region that must not dangle).</li>
</ul>



<a name="234993032"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234993032" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234993032">(Apr 17 2021 at 14:45)</a>:</h4>
<p>then basically <code>(*ptr).field</code> would assert that <code>ptr</code> points to a large enough piece of memory to hold the entire type it is designated to have.</p>



<a name="234993040"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234993040" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234993040">(Apr 17 2021 at 14:45)</a>:</h4>
<p>this might be surprising to some, but it is also more symmetric.</p>



<a name="234993337"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234993337" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234993337">(Apr 17 2021 at 14:50)</a>:</h4>
<p>I like that rule (for the stage 1 proposal... I'm still holding out hope for my proposal as stage 2)</p>



<a name="234993508"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234993508" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234993508">(Apr 17 2021 at 14:53)</a>:</h4>
<p>The way I would explain it is that using the projection<code>Foo.field</code> you are asserting that <code>p</code> actually points to a <code>Foo</code> (or at least there is a set of bytes that could potentially be a <code>Foo</code> pointed to by <code>p</code>), and so <code>(*p).field</code> is also dereferenceable</p>



<a name="234999119"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234999119" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234999119">(Apr 17 2021 at 16:09)</a>:</h4>
<p>as written this would also apply to array and slice indexing</p>



<a name="234999494"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/234999494" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#234999494">(Apr 17 2021 at 16:16)</a>:</h4>
<p>A downside is that this rule has <em>more</em> UB than LLVM strictly requires, so there might be code in the wild that is made UB by this</p>



<a name="235003771"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/235003771" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#235003771">(Apr 17 2021 at 17:19)</a>:</h4>
<p><span class="user-mention silent" data-user-id="271719">Mario Carneiro</span> <a href="#narrow/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref/near/234999494">said</a>:</p>
<blockquote>
<p>A downside is that this rule has <em>more</em> UB than LLVM strictly requires, so there might be code in the wild that is made UB by this</p>
</blockquote>
<p>well, the rule has less UB than we have currently</p>



<a name="235003778"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/235003778" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#235003778">(Apr 17 2021 at 17:19)</a>:</h4>
<p>so no code is <em>made</em> UB by this, that code <em>already</em> is UB</p>



<a name="235003784"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/Alignment%20and%20raw%20pointer%20deref/near/235003784" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/Alignment.20and.20raw.20pointer.20deref.html#235003784">(Apr 17 2021 at 17:19)</a>:</h4>
<p>but we are leaving a chance on the table to make it not UB</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>